在使用Matplotlib进行可视化的过程中,为了更直观的展示数据大小,往往会在图形中标注具体数值,比如数值大小标注在直方图。本文将通过一个实际案例详细讲解如何标注数据。同时还会介绍一个比较风骚的操作,那就是Matplotlib的嵌入图像(将小图像嵌入到大图像中),学会这个最后就可以画出这种图形化的数据标注了。演示用的数据集是2016年入境美国人数(arrivalsinUnitedStates)前十位国家的数据,包括国名和具体移民人数。人数的具体单位是百万人。%matplotlibinlineplt.rcParams['font.sans-serif']='SimHei'x_data=['加拿大','墨西哥','英国','日本','中国','德国','韩国','法国','巴西','印度']y_data=[13.428347,12.255948,3.019111,2.352919,2.09833,1.322882,1.282097,1.127868,1.109066,0.874016]有了数据就可以画直方图了=figlt.axsubplots(figsize=(16,6))ax.bar(x_data,y_data)接下来开始添加标注,即在直方图上显示具体的数值。在Matplotlib中,有两种方法可以给数据添加注释,一种是使用ax.text(),另一种是ax.annotate()。ax.text()ax.text()的主要作用是给图片添加一些文字,也就是文字。不仅可以添加注释,还可以在图形上的任意坐标添加文字,只要指定坐标即可。函数中的几个重要参数,具体介绍一下x:x的坐标y:y的坐标s:要添加的文字rotation:文字旋转的角度fontsize:文字的字体大小fontweight:文字字体的粗细它需要注意的是每次调用ax.text()一次只能生成一个Text对象,也就是说一次只能添加一条评论。如果有多个,则需要写一个循环来生成。所以一般添加标注的过程是这样一个过程:先确定标注的横纵坐标-->写一个循环调用ax.text()fig,ax=plt.subplots(figsize=(16,6))ax.bar(x_data,y_data)#循环生成文本#horizo??ntalalignment参数设置注释居中显示forx,yinzip(x_data,y_data):ax.text(x,y+0.05,y,fontsize=14,horizo??ntalalignment='center')关于图表美化,这里暂时不过再重复一遍。ax.annotate()和ax.text()相比,ax.annotate()更像是为标注而生,annotate就是标注的意思。ax.annotate()的注解功能更强大。除了添加文字注释外,还可以根据需要添加箭头→来表示。一些主要的参数如下:s:标注文本xy:需要标注的数据点的位置xytext:文本标注的位置,默认为xyarrowprops:控制箭头属性的dict,如果你需要显示箭头,这里必须设置两个比较有意思的参数,xy和xytext。两者之间似乎没有区别。这个地方确实容易引起混乱。一般来说,s和xy是必须设置的参数。如果不指定,xytext默认与xy相同。但是如果要设置箭头,xy的坐标定义了箭头的头部,xytext指定了箭头的尾部和文字标注的位置。其实可以画个图来理解。ax.annotate()和ax.text()的绘制过程是一样的,都需要循环生成注解。不设置箭头,简单添加注释fig,ax=plt.subplots(figsize=(16,6))ax.bar(x_data,y_data)forx,yinzip(x_data,y_data):ax.annotate(y,(x,y+0.05),fontsize=14,horizo??ntalalignment='center')添加注释并设置箭头fig,ax=plt.subplots(figsize=(16,6))ax.bar(x_data,y_data)#Arrowheadcoordinates(x,y)#箭头尾坐标(注释坐标)为(x,y+1)forx,yinzip(x_data,y_data):ax.annotate(y,xy=(x,y),xytext=(x,y)+1),fontsize=14,horizo??ntalalignment='center',arrowprops=dict(arrowstyle='->'))#扩大纵坐标范围ax.set_ylim([0,16])设置显示箭头后,可以明显的看出箭头是从xytext的坐标指向xy的坐标,所以在不需要设置箭头的时候,设置xytext的意义不大。嵌入式图您可能会使用较少的嵌入式图,但此类图实际上非常有用。以上面的数据例子为例,直方图展示了2016年到达美国的前十个国家的具体人数。如果要分析各个国家到达美国人数的比例区域,你应该怎么画呢?更直接的思路是使用subplots子图,比如上面是直方图,下面是饼图,如下:zhou_name=['西欧','亚洲','南美','大洋洲','加勒比海','中东','中美洲','东欧','非洲']zhou_percent=[36.2,30.8,13.9,4.3,4.1,3.8,2.8,2.6,1.5]fig,ax=plt.subplots(2,1,figsize=(16,12))ax[0].bar(x_data,y_data)forx,yinzip(x_data,y_data):ax[0].annotate(y,(x,y+0.05),fontsize=14,horizo??ntalalignment='center')ax[1].pie(zhou_percent,labels=zhou_name,autopct='%1.1f%%')这个当然是可行的,但是还有更好的方案,就是嵌入图像。注意这里直方图右边有一大块空白。如果把饼图放在直方图右侧的空白部分会更直观。生成内联图有两种方法,一种是fig.add_axes(),另一种是使用inset_axes()。fig.add_axes()fig.add_axes()就是在原来的Figure上增加一个新的区域Axes,然后在这个区域绘制图形。如果使用这种方式,需要指定新添加的Axes在图中的相对位置和面积大小。输入的参数都是和原图成正比的,如下:#left和bottom控制新Axes的位置#width和height控制新Axes的大小(长和宽)#这些都是用相对数表示的,大小在0-1之间left,bottom,width,height=[0.5,0.3,0.5,0.5]fig,ax1=plt.subplots(figsize=(16,6))ax1.bar(x_data,y_data)forx,yinzip(x_data,y_data):ax1.annotate(y,(x,y+0.05),fontsize=14,horizo??ntalalignment='center')#使用fig.add_axes()添加新区域Axes绘图ax2=fig.add_axes([left,bottom,width,height])ax2.pie(zhou_percent,labels=zhou_name,autopct='%1.1f%%')对比inset_axes因为fig.add_axes()需要调试相对位置,使用inset_axes()为绘图可以方便定位。inset_axes中的位置由参数loc设置,可以用字符串或数字控制,如下:'upperright':1'upperleft':2'lowerleft':3......'uppercenter':9'center':10#使用前需要pilot包frommpl_toolkits.axes_grid1.inset_locatorimportinset_axesfig,ax1=plt.subplots(figsize=(16,6))ax1.bar(x_data,y_data)forx,yinzip(x_data,y_data):ax1.annotate(y,(x,y+0.05),fontsize=14,horizo??ntalalignment='center')#右边放inset图片,宽和长是相对长度ax2=inset_axes(ax1,width='60%',height='60%',loc='right')ax2.pie(zhou_percent,labels=zhou_name,autopct='%1.1f%%')美化这里就不多说了,参考这篇文章详细介绍了如何用Matplotlib画出好看的图形。
