近非常流行动态条形图,在各个APP都有百万播放量,我参考很多优秀的人文章,最终实现动态条形图的生成;生成的效果如图:
我也是一名某科大大数据专业的在校大学生,也会遇到很多形形色色的问题,所以每一步都做的很踏实,结果很清楚。后续也会出一些很实用的代码以很直观的方式展示出来,有好的方法大家 也可以一起讨论讨论。
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import matplotlib.animation as animation
from IPython.display import HTML
import gif
df = pd.read_excel('江苏省2018~2021年人均gdp对比图.xlsx')
df.head(5)
current_year = 2018
dff = (df[df['year'].eq(current_year)]
.sort_values(by='人均GDP', ascending=False)
.head(13))
以下是2018年江苏省13市的人均GDP数据
3.展示条形图
plt.rcParams['font.sans-serif']=['SimHei'] #显示中文标签
fig, ax = plt.subplots(figsize=(15, 8))
ax.barh(dff['city'], dff['人均GDP'])
plt
df = pd.read_excel('江苏省2018~2021年人均gdp对比图.xlsx')
city_list = list(set(df.city))
# randomcolor生成颜色代码原理,
# 【1-9/A-F】15个数字随机组合成6位字符串前面再加上一个“#”号键
import random
def randomcolor():
colorlist = ['1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']
color =''
for i in range(6):
color += random.choice(colorlist)
return '#'+ color
city_color = {}
for city in city_list:
city_color[city] = randomcolor()
def draw_barchart(current_year):
dff = df[df['year'].eq(current_year)].sort_values(by='人均GDP',ascending = True)
ax.clear()
ax.barh(dff['city'],dff['人均GDP'],color = [city_color[x] for x in dff['city']]) #ax.bar是一般的条形图,barh是水平的条形图,h是horizontal的意思
dx = dff['人均GDP'].max()/200
for i ,(value,name) in enumerate(zip(dff['人均GDP'], dff['city'])):
ax.text(value+dx,i ,f'{value:,.0f}',size = 14,ha = 'left',va ='center')
ax.text(1,0.4,current_year,transform = ax.transAxes,color ='#777777',size = 16,ha ='right',weight=800)
ax.text(0,1.06,'人',transform = ax.transAxes,size=12,color='#777777')
#set_major_formatter表示刻度尺格式;
ax.xaxis.set_major_formatter(ticker.StrMethodFormatter('{x:,.0f}'))
ax.xaxis.set_ticks_position('top')
ax.tick_params(axis='x',colors='#777777',labelsize=12)
# ax.set_yticks([]) #set_yticks([])表示不显示y轴的取值
#margins表示自动缩放余额;
ax.margins(0,0.01)
# 设置后面的网格
ax.grid(which='major',axis='x',linestyle='-')
#刻度线和网格线是在图标上方还是下方,True为下方
ax.set_axisbelow(True)
ax.text(0,1.15,'2018-2021年江苏省13市GDP排名',
transform=ax.transAxes,size=24,weight=600,ha='left',va='top')
ax.text(1,0,'by 小yang',transform = ax.transAxes,color ='#777777',ha = 'right',
bbox = dict(facecolor='white',alpha = 0.8,edgecolor='white'))
#取消图表周围的方框显示
plt.box(False)
#plt.savefig('{}.jpg'.format(current_year))保存图片,用在gif图
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] #设置汉字字体
fig, ax = plt.subplots(figsize=(15, 8))#设置画布大小
animator = animation.FuncAnimation(fig, draw_barchart, frames=range(2018, 2022),interval=700) #interval越大速度越慢
HTML(animator.to_jshtml())
#如果要保存html,用一下代码
'''with open("2018-2021年江苏省13市GDP排名.html", "w") as f:
print(animator.to_jshtml(), file=f)'''
以下使用HTML(animator.to_jshtml())跑出来的数据,下面的按钮点击就可以实现动态变化。
1.根据网上代码制作
animator.save('test.gif',writer='imagemagick')
虽然已gif格式出来了,但是图片出现了重叠的现象。对于一张图数据变化简单,这个方法并不能满足我们的需求
2.利用图片生成gif
通过观察发现如果想实现理想状态,需要对每一张图前再加一张空白的页面。就可以实现目标,会的可以在评论区说一说。我根据第4步画条形图的函数中,将每张图片保存。
plt.savefig('{}.jpg'.format(current_year))保存图片,用在gif图
接下来循环,获取2018~2021年江苏省人均GDP的图片
for i in range(2018,2022):
fig, ax = plt.subplots(figsize=(15, 8))
draw_barchart(i)
获取图片将他们放在 一个合适的文件夹中,接下来就是图片变成gif
#系统操作库
import os
# 图片处理库
from PIL import Image
# 初始化图片地址文件夹途径
image_path = 'image/'
# 获取文件列表
files = os.listdir(image_path)
# 定义第一个文件的全局路径
file_first_path = os.path.join(image_path, files[0])
# 获取Image对象
img = Image.open(file_first_path)
# 初始化文件对象数组
images = []
for image in files[1:]:
# 获取当前图片全量路径
img_path = os.path.join(image_path, image)
# 将当前图片使用Image对象打开、然后加入到images数组
images.append(Image.open(img_path))
# 保存并生成gif动图
img.save('2018-2021年江苏省13市GDP排名.gif', save_all=True, append_images=images, loop=0, duration=700)
这样就可以完美生成gif了 ,恭喜啊
import random
import matplotlib
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import random
import matplotlib.animation as animation
from IPython.core.display import HTML
import gif
df = pd.read_excel('江苏省2018~2021年人均gdp对比图.xlsx')
city_list = list(set(df.city))
def randomcolor():
colorlist = ['1','2','3','4','5','6','7','8','9','A','B','C','D','E','F']
color =''
for i in range(6):
color += random.choice(colorlist)
return '#'+ color
# 构造一个name_color字典
city_color = {}
for city in city_list:
city_color[city] = randomcolor()
#定义一个画条形图的函数:
def draw_barchart(current_year):
dff = df[df['year'].eq(current_year)].sort_values(by='人均GDP',ascending = True)
ax.clear()
ax.barh(dff['city'],dff['人均GDP'],color = [city_color[x] for x in dff['city']]) #ax.bar是一般的条形图,barh是水平的条形图,h是horizontal的意思
dx = dff['人均GDP'].max()/200
for i ,(value,name) in enumerate(zip(dff['人均GDP'], dff['city'])):
ax.text(value+dx,i ,f'{value:,.0f}',size = 14,ha = 'left',va ='center')
ax.text(1,0.4,current_year,transform = ax.transAxes,color ='#777777',size = 16,ha ='right',weight=800)
ax.text(0,1.06,'人',transform = ax.transAxes,size=12,color='#777777')
#set_major_formatter表示刻度尺格式;
ax.xaxis.set_major_formatter(ticker.StrMethodFormatter('{x:,.0f}'))
ax.xaxis.set_ticks_position('top')
ax.tick_params(axis='x',colors='#777777',labelsize=12)
# ax.set_yticks([]) #set_yticks([])表示不显示y轴的取值
#margins表示自动缩放余额;
ax.margins(0,0.01)
# 设置后面的网格
ax.grid(which='major',axis='x',linestyle='-')
#刻度线和网格线是在图标上方还是下方,True为下方
ax.set_axisbelow(True)
ax.text(0,1.15,'2018-2021年江苏省13市GDP排名',
transform=ax.transAxes,size=24,weight=600,ha='left',va='top')
ax.text(1,0,'by 小yang',transform = ax.transAxes,color ='#777777',ha = 'right',
bbox = dict(facecolor='white',alpha = 0.8,edgecolor='white'))
#取消图表周围的方框显示
plt.box(False)
plt.savefig('{}.jpg'.format(current_year))
plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'] #设置汉字字体
fig, ax = plt.subplots(figsize=(15, 8))#设置画布大小
animator = animation.FuncAnimation(fig, draw_barchart, frames=range(2018, 2022),interval=700) #interval越大速度越慢
#保存到jshtml
#HTML(animator.to_jshtml())
#HTML(animator.to_jshtml())
'''with open("2018-2021年江苏省13市GDP排名.html", "w") as f:
print(animator.to_jshtml(), file=f)'''
animator.save('test.gif',writer='imagemagick')
# windows需要安装imagemagick软件,并配置到系统路径中
for i in range(2018,2022):
fig, ax = plt.subplots(figsize=(15, 8))
draw_barchart(i)
2.将图片找到位置保存,然后生成gif
#系统操作库
import os
# 图片处理库
from PIL import Image
# 初始化图片地址文件夹途径
image_path = 'image/'
# 获取文件列表
files = os.listdir(image_path)
# 定义第一个文件的全局路径
file_first_path = os.path.join(image_path, files[0])
# 获取Image对象
img = Image.open(file_first_path)
# 初始化文件对象数组
images = []
for image in files[1:]:
# 获取当前图片全量路径
img_path = os.path.join(image_path, image)
# 将当前图片使用Image对象打开、然后加入到images数组
images.append(Image.open(img_path))
# 保存并生成gif动图
img.save('2018-2021年江苏省13市GDP排名.gif', save_all=True, append_images=images, loop=0, duration=700)