Python-matplotlib 商业图表-第5弹

2021-02-22 11:59:50 浏览数 (1)

1 引言

第一次使用 Markdown Nice 进行公众号编写(其实刚开始运营公众号时也有使用过,奈于代码编辑就放弃,不过,现在“真香”了 ),希望熟悉后定制自己属于自己的主题。本期还是继续前面的Python-matplotlib 商业图表绘制系列的第5篇教程推文,目的还是为了熟悉matplotlib的绘图语法。

2 数据可视化设计

今天我们是为了仿制一幅可视化作品(如下图),也是看到一位朋友使用R-ggplot2 进行仿制,所以就使用Matplotlib 进行了再现

。由于下面子图部分绘图技巧较为单一,我们我们今天主要绘制图的上半部分(图中红框部分)。主要涉及的matplotlib绘图技巧如下:

  • ax.plot()绘制自定义化散点图。
  • ax.scatter()绘制散点。看过我之前教程的小伙伴会发现,我是经常使用此方法进行图表设计。
  • ax.fill_between()绘制填充。
  • ax.text()文本添加。
  • 其他图刻度、坐标轴、字体等图层属性均涉及到。

(上述图片来源于朋友的公众号)

Python-matplotlib 仿制代码如下:

代码语言:javascript复制
// FileName: plot05.py 
//@NingHaitao
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1.inset_locator import inset_axes

#读取数据
data = pd.read_excel(r"F:DataCharm商业艺术图表仿制us-china.xlsx")

x = [i for i in np.arange(0,8,1)]
x2 = [i for i in np.arange(0,len(data) 1,1)]
china_value = data['China Cumulative values'][:7].to_list()
us_value = data['US Cumulative values'][:7].to_list()
china_ta = data["China Cumulative target"].to_list()
us_ta = data['us Cumulative target'].to_list()

#由于原图中“原点”是用连接线的,而具体的数值是没有的,这里我们给需要绘制的数据都添加数值0
#简单的列表追加即可
china_list = [0]
us_list = [0]
china_tar = [0]
us_tar = [0]

for china in china_value:
    china_list.append(china)
for us in us_value:
    us_list.append(us)
for china_t in china_ta:
    china_tar.append(china_t)
for us_t in us_ta:
    us_tar.append(us_t)
    
#开始绘图
fig,ax = plt.subplots(figsize=(9,5),dpi=200)

line01 = ax.plot(x2,china_tar,"--",color='#821616')
#绘制圆点
scatter01 = ax.scatter(x2[-1],china_tar[-1],color='#821616',s=30)
line02 = ax.plot(x2,us_tar,"--",color='#4D7DA5')
scatter02 = ax.scatter(x2[-1],us_tar[-1],color='#4D7DA5',s=30)

#绘制填充阴影
ax.fill_between(x2,china_tar,color='#B7004F',alpha=.1,fc='none',lw=.1)
ax.fill_between(x2,us_tar,color="#3D719D",alpha=.2,fc='none',lw=.1)

ax.fill_between(x2[:8],china_tar[:8],color='#B7004F',alpha=.2,fc='none',lw=.1)
ax.fill_between(x2[:8],us_tar[:8],color="#3D719D",alpha=.3,fc='none',lw=.1,zorder=2)

china_line = ax.plot(x,china_list,marker='o',color='#821616',zorder=2)
us_line = ax.plot(x,us_list,marker='o',color="#172A3A",zorder=2)

#添加文本
ax.text(x[-1] .2,china_list[-1] 6,"$48.5 billion",ha='left',
        va='center',color='#821616',fontweight='bold',size=8.5)
ax.text(x[-1] .2,china_list[-1],"actual purchases based on Chinese imports",ha='left',
        va='center',color='#821616',fontweight='light',size=8)
ax.text(x[-1] .2,us_list[-1]-1,"$39.4 billion",ha='left',
        va='center',color='#172A3A',fontweight='bold',size=8.5)
ax.text(x[-1] .2,us_list[-1]-7,"actual purchases based on US imports",ha='left',
        va='center',color='#172A3A',fontweight='light',size=8)
#定制化绘制
ax.grid(color='#4D7DA5',lw=.5,alpha=.5)
ax.tick_params(left=False,right=False,top=False,labelsize=10,colors='#4D7DA5',direction='in',length=4)
for spine in ['top','right']:
    ax.spines[spine].set_color('none')
for spine in ['left','bottom']:
    ax.spines[spine].set_color('#4D7DA5')
ax.set_ylim(bottom=0,top=180)
ax.set_xlim(left=0,right=12.1)
ax.set_xticks(np.arange(0, 13, step=1))
#这里我们直接设置刻度lebels,和前面一样,我们添加“”作为原点的刻度lebel,即无刻度标签
labels = [""]
for label in data.date.to_list():
    labels.append(label)
ax.set_xticklabels(labels)

#添加额外文本
ax.text(0,1.05,"US exports and China's imports of all covered goodsnin 2020,as of july,billions USD",
        transform = ax.transAxes,color='#3B4B59',ha='left',size=8.5)
ax.text(.75,1.05,"Purchase commitmentn(Chinese imports)",
        transform = ax.transAxes,color='#BD145D',ha='right',size=8)
ax.text(.75,1.01,"$172.7 billion",fontweight='bold',
        transform = ax.transAxes,color='#BD145D',ha='right',size=8)

ax.text(1,1.05,"Purchase commitmentn(US imports)",
        transform = ax.transAxes,color='#5280A8',ha='right',size=8)
ax.text(1,1.01,"$142.7 billion",fontweight='bold',
        transform = ax.transAxes,color='#5280A8',ha='right',size=8)
#title
ax.text(.5,1.3,"US-China phase one tracker:China's purchases of US goods",fontweight='bold',
        transform = ax.transAxes,color='#3D719C',ha='center',va='center',size=15)
#添加横线:使用额外的inset_axes方法进行重新插入。
line = inset_axes(ax,width=7.7, height=.4,loc='upper center',
                  bbox_to_anchor=(0.0, 0.3, 1, 1),
                  bbox_transform=ax.transAxes,
                  borderpad=0)
line.plot([.1,.7],[.1,.1],color='#5684AA',lw=1.5)
line.axis('off')
#subtitle
ax.text(.5,1.2,"US exports and China's exports in 2020 of all goods covered by the phase one deal as of July 2020",
        transform = ax.transAxes,color='#3D719D',ha='center',va='center',size=10)

ax.text(.89,.04,'nVisualization by DataCharm',transform = ax.transAxes,
        ha='center', va='center',fontsize = 6,color='black',fontweight='bold',family='Roboto Mono')

plt.savefig(r'F:DataCharm商业艺术图表仿制US_China_Exports.png',width=8,height=4,
            dpi=900,bbox_inches='tight')

最终可视化结果如下:

再现的效果还是很不错哦

3 总结

具体的绘图方法不是很难,个人认为这是一个作为练习 ax.fill_between()的一个很好的练习,同时对文本图层的添加(即直接替代title属性添加)。关键代码部分都有详细的解释,关注公众号并后台回复"商业图表仿制05"即可获得本次的绘图数据。

为了大家更好的学习交流,DataCharm的学习交流群已经建立,由于群的二维码连接易失效,可以通过扫面下方二维码,添加本人微信,备注姓名哦(如数据可视化-张三)。我拉你入群

。偷偷告诉你,群里的大牛是真多哦

0 人点赞