超动感,百行Python代码制作动态气泡图
Python与算法之美
共 4337字,需浏览 9分钟
· 2021-06-12
先上图片:
再上视频:
最后上代码:
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
import matplotlib.animation as animation
import imageio
import os
import cv2
from PIL import Image
plt.rcParams['animation.writer'] = 'html'
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
def html_to_gif(html_file, gif_file, duration=0.1):
path = html_file.replace(".html","_frames")
images = [os.path.join(path,x) for x in sorted(os.listdir(path))]
frames = [imageio.imread(x) for x in images]
imageio.mimsave(gif_file, frames, 'gif', duration=duration)
return gif_file
cmap = [
'#2E91E5',
'#1CA71C',
'#DA16FF',
'#B68100',
'#EB663B',
'#00A08B',
'#FC0080',
'#6C7C32',
'#862A16',
'#620042',
'#DA60CA',
'#0D2A63']*100
dfx = pd.read_csv("./data/gdp_per_capita.csv")
dfx = dfx.set_index("year")
dfx.index = [str(x) for x in dfx.index]
dfx = dfx[sorted(dfx.columns)]
dfy = pd.read_csv("./data/life_expect.csv")
dfy = dfy.set_index("year")
dfy.index = [str(x) for x in dfy.index]
dfy = dfy[sorted(dfy.columns)]
dfz = pd.read_csv("./data/pop_amount.csv")
dfz = dfz.set_index("year")
dfz.index = [str(x) for x in dfz.index]
dfz = dfz[sorted(dfz.columns)]
def bubble_chart_race(dfx,dfy,dfz,title = "中国大陆各省市历年人均GDP和预期寿命变化",
filename = None,
figsize = (6.5,3.5),dpi = 144,
duration = 0.5,
xlabel = "人均GDP(人民币)",
ylabel = "预期寿命",
size_label = "点尺寸: 人口数量",
anotate_points = ["江西省","北京市","上海市","广东省",
"河南省","江苏省","黑龙江省","西藏自治区"]):
fig,ax = plt.subplots(figsize=figsize,dpi=dpi)
ax.set_facecolor("0.9")
ax.set_title(title,color = "black",fontsize = 12)
# 调整spines
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.spines["left"].set_visible(False)
ax.spines["bottom"].set_visible(False)
def plot_frame(date):
dfdata = pd.DataFrame()
xdata = dfx.loc[date,:].sort_index()
ydata = dfy.loc[date,:].sort_index()
zdata = dfz.loc[date,:].sort_index()
dfdata["x"] = xdata
dfdata["y"] = ydata
dfdata["z"] = zdata
# 绘制散点图像
ax.clear()
ax.scatter(dfdata["x"],dfdata["y"],s = 100*dfdata["z"]/dfdata["z"].mean(),
c = (cmap*100)[0:len(dfdata)],alpha = 0.5)
# 添加图例文字
for i,p in enumerate(dfdata.index):
px,py,pz = dfdata.loc[p,["x","y","z"]].tolist()
if p in anotate_points:
ax.annotate(p,xy = (px,py), xycoords = "data",
xytext = (-15,10),fontsize = 10,fontweight = "bold",color = cmap[i], textcoords = "offset points")
ax.tick_params(bottom = False,left = False,labelsize = 8,direction = "in",length = 2)
# 调整绘图范围
xlim = (dfx.values.min(),dfx.values.max())
ax.set_xlim(left = xlim[0]-(xlim[1]-xlim[0])/10,right = xlim[1]+(xlim[1]-xlim[0])/10)
ylim = (dfy.values.min(),dfy.values.max())
ax.set_ylim(bottom = ylim[0]-(ylim[1]-ylim[0])/10,top = ylim[1]+(ylim[1]-ylim[0])/5)
# 添加辅助元素
ax.text(0.5, 0.5, date, va="center", ha="center",alpha=0.3, size = 50,transform = ax.transAxes)
ax.text(0.85, 0.92, size_label, ha="center",va="center", size = 10,transform = ax.transAxes)
ax.grid(axis = "x",color="white",lw=1,ls = "-")
ax.tick_params(bottom = False,left = False,labelsize = 8,direction = "in",length = 2)
ax.set_xlabel(xlabel,fontsize = 10)
ax.set_ylabel(ylabel,fontsize = 10)
bubble_animation = animation.FuncAnimation(fig,plot_frame,frames = dfx.index ,interval = int(duration*1000))
if filename is None:
try:
from IPython.display import HTML
return HTML(bubble_animation.to_jshtml())
except ImportError:
pass
else:
bubble_animation.save(filename)
return filename
html_file = "bubble_chart_race.html"
gif_file = html_file.replace(".html",".gif")
bubble_chart_race(dfx,dfy,dfz,filename = html_file,title = "中国大陆各省份历年人均GDP和预期寿命")
html_to_gif(html_file,gif_file,duration=1.0)
主要思路是构建plot_frame函数逐帧绘制图像,再用matplotlib的animation模块制作动画。
收工。😋
打码不易,喜欢本篇的小伙伴,或者需要完整代码和绘图数据集的同学,可以对本文点赞,在看,和分享后在公众号“算法美食屋”后台回复关键字:动态图,添加作者微信获取。
万水千山总是情,点个在看行不行。。。😋
评论
金融研究 | 使用Python测量关键审计事项的「信息含量」
Tips: 公众号推送后内容只能更改一次,且只能改20字符。如果内容出问题,或者想更新内容, 只能重复推送。为了更好的阅读体验,建议阅读本文博客版, 链接地址https://textdata.cn/blog/2023-01-13-information-content-of-critical-aud
大邓和他的Python
0
金融研究(更新) | 使用Python构建关键审计事项的「信息含量」
Tips: 公众号推送后内容只能更改一次,且只能改20字符。如果内容出问题,或者想更新内容, 只能重复推送。为了更好的阅读体验,建议阅读本文博客版, 链接地址https://textdata.cn/blog/2023-01-13-information-content-of-critical-aud
大邓和他的Python
0
阿里的同事,写的代码真 TMD 优雅!
通过这篇文章你将了解到整洁的代码对项目、公司和你的重要性,以及如何书写整洁的代码.通过命名、类、函数、测试这四个章节,使我们的代码变得整洁.1、为什么要保持代码整洁?不整洁的代码随着时间的增加而增加时,生产力会随之降低.导致的结果就是:代码不易扩展或扩展容易引发其他问题程序崩溃加班增加公司成本(加人
Java专栏
1
老爸嘲讽我了,写破代码一年就挣十几万,他在工地带50个工人,一个月光人头费就3万,让我滚回去跟他干!
点击上方 "大数据肌肉猿"关注, 星标一起成长点击下方链接,进入高质量学习交流群今日更新| 1052个转型案例分享-大数据交流群来自:网络,侵删有个网友的父亲是做工程的,天天就嘲笑他,说他天天写着破代码有啥用,一年就拿个十多万的死工资,然后告诉他自己在工地里面带了50个工人,一个月能抽三万
程序源代码
0
谷歌员工爆料 Python 基础团队原地解散
转自 | 机器之心编辑 | 蛋酱什么?谷歌解雇了整个 Python 基础团队?「当与你直接共事的每个人,包括你的主管,都被裁员 —— 哦,是职位被削减,而你被要求安排他们的替代者入职,这些人被告知在不同的国家担任同样的职位,但他们并不为此感到高兴,这是很艰难的一天。」发布这一动态的 Tho
机器学习算法与Python实战
0
五一抢票难,Github上这几个Python项目,你可以试试
又到五一长假啦(虽然其实就放了1天),大家是打算家里蹲or出去玩,又或者是在公司加班呢...今天给大家介绍三个和12306相关的项目,看看你是否用得上。/01/ py12306py12306购票助手,顾名思义,12306买票的~需要在python 3.6以上版本运行程序。1. 安装依赖gi
Crossin的编程教室
0
谷歌员工爆料Python基础团队原地解散
机器之心报道编辑:蛋酱什么?谷歌解雇了整个 Python 基础团队?「当与你直接共事的每个人,包括你的主管,都被裁员 —— 哦,是职位被削减,而你被要求安排他们的替代者入职,这些人被告知在不同的国家担任同样的职位,但他们并不为此感到高兴,这是很艰难的一天。」发布这一动态的 Thomas Wouter
机器学习初学者
0
Python加速运行技巧
Python 是一种脚本语言,相比 C/C++ 这样的编译语言,在效率和性能方面存在一些不足。但是,有很多时候,Python 的效率并没有想象中的那么夸张。本文对一些 Python 代码加速运行的技巧进行整理。 0. 代码优化原则 本文会介绍不少的 Python 代码加速运行的技巧。在深入代码优化细
机器学习算法与Python实战
0