今日表情?
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAjM2EzLcd3LcJzLcJzdllmVldWYtl2Pml2ZucTMllTN4YWZxEGOyIGOyczNzUWNxEWMwU2YzczMzETYvwlN2gDO1kDNtUGall3LcVmdhNXLwRHdo9CXt92YucWbpRWdvx2Yx5yazF2Lc9CX6MHc0RHaiojIsJye.gif)
樹地圖(tree map)是一種适用于顯示大量分層結構的資料,它是餅狀圖的一種高次元替代者,可以用面積直覺顯示各個部分的占比。
先上圖檔:
再上視訊:
最後上代碼:
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
import squarify
cmap = [
'#2E91E5',
'#1CA71C',
'#DA16FF',
'#B68100',
'#EB663B',
'#00A08B',
'#FC0080',
'#6C7C32',
'#862A16',
'#620042',
'#DA60CA',
'#0D2A63']*100
plt.rcParams['animation.writer'] = 'html'
plt.rcParams['font.family'] = ['sans-serif']
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
df = pd.read_csv('./data/gdp_china_1993_2019.csv')
df["date"] = [str(x) for x in df["date"]]
df = df.set_index("date")
df.columns = [x if "自治區" not in x else x[0:2] for x in df.columns]
df = df.sort_values("2019",axis = 1,ascending=False)
figsize = (8,6)
dpi = 160
title = "中國大陸各省份曆年GDP"
n_visible = 31
def treemap_dance(df,filename = None,
title = "中國大陸各省份曆年GDP",figsize = (8,6),dpi = 120,duration = 2,n_visible= 31):
assert filename is None or filename.endswith(".html"), "filename should like *.html!"
fig,ax = plt.subplots(figsize=figsize,dpi=dpi)
# 調整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(i):
ax.clear()
date = df.index[i]
dfdata = pd.DataFrame(df.loc[date,:])
dfdata.columns = ["values"]
dfdata["color"] = [cmap[i] for i in range(len(dfdata))]
dfdata = dfdata.sort_values("values",ascending = True)
dfused = dfdata.iloc[n_visible::-1,:]
xdata = dfused.index.tolist()
ydata = dfused["values"].tolist()
colors = dfused["color"].tolist()
#plt.rc('font', size=7,color = "white")
squarify.plot(sizes = ydata, # 指定繪圖資料
label = xdata, # 指定标簽
color = colors, # 指定自定義顔色
alpha = 0.5, # 指定透明度
value = ydata, # 添加數值标簽
edgecolor = 'white', # 設定邊界框為白色
linewidth =3, # 設定邊框寬度為3
ax = ax,
text_kwargs = {"size":8,"color":"black"},
zorder = 0
)
#輔助設定
ax.set_title(title,color = "black",fontsize = 12)
ax.text(0.08, 0.92, str(date), va="center", ha="center",
alpha=1.0, color ="white", size = 20,transform = ax.transAxes)
plt.axis('off')
plt.tick_params(top = 'off', right = 'off')
my_animation = animation.FuncAnimation(fig,plot_frame,frames = range(0,len(df)),interval = int(duration*1000))
if filename is None:
try:
from IPython.display import HTML
HTML(my_animation.to_jshtml())
return HTML(my_animation.to_jshtml())
except ImportError:
pass
else:
my_animation.save(filename)
return filename
treemap_dance(df)
html_file = "treemap_dance.html"
gif_file = "treemap_dance.gif"
treemap_dance(df, filename = html_file)
html_to_gif(html_file,gif_file,duration=1.0)
複制
主要原理是安裝并使用了squarify 庫來繪制樹地圖,并借助 matplotlib中的 animation制作動态圖。
收工。?