赞
踩
Matplotlib可以说是Python最声名远扬的可视化库了,也是Python数据分析库的“三驾马车”之一。Matplotlib是基础而非常强大的可视化库,Seaborn等好用的可视化库是在前者的基础上进行的封装。Matplotlib擅长快速出简单的图、有丰富的接口进行精细化绘图、和Numpy结合做科学可视化及三维图配合默契、三维图。但也有些缺点,如不容易基于实用目的绘制有一定难度的图表(如小提琴图等)、标签等元素需指定坐标而不能自适应优化显示、难以实现交互。
官网说:
Matplotlib tries to make easy things easy and hard things possible.
我越用越认可这句话,Matplotlib非常强大,Hard things是possible但并非easy and fast。
对于一个数据表df(通过pandas读入为DataFrame)来说,用Matplotlib对其进行可视化的基础框架为:
fig, ax = plt.subplots()ax.plot(df['x'],df['y'])
通过上面几行代码就可以画出df表周一到周五y指标的变化折线。
Matplotlib其实为作图提供了两套可视化接口:
根据官网教程,分别对应MATLAB的陈述式语法和面向对象写法,
个人理解,plt.plot()适合用于快速出图,读入一个数据表后想快速知道数据分布、指标关系等,通过plt.plot()系列语句直接出图,而ax.plot()更方便用来精细绘图,接口对各种图表元素的编辑很友好。
在Matplotlib官网搜索,通常能看到两套接口,如搜绘制饼图的关键词pie,结果中的axes.Axes.pie对应ax.pie()的用法,pyplot.pie对应plt.pie()的函数接口。
ax.×××()的写法看起来要写的语句多些,但这种面向对象(object-oriented)的写法通过fig, ax = plt.subplots()建立画布(figure)和定义轴域(axes),能更明确在哪作画和映射规则,给用户更大的自由度和更精细的调参能力。Axes包含了一套坐标轴(axis),确定了x/y坐标轴之后,数值再确定对应坐标,也就唯一确定了所在位置(这是二维情况下,更高维度就会对应着更多的axis),散点图是去确定点在轴域下的位置,柱状图是确定每个柱柱所在的位置,因此一套Axes就确定了唯一的独立的图,一个画布可以有多套Axes。简单说就是ax.×××()更方便调细节,初学者尽量避免用plt.×××系列来画图。
基础图表绘制
数据可视化从目的来说,是为了更直观展示数据或数据之间的对比、分布或关联关系。散点图、折线图、柱状图、条形图、饼图、直方图是非常常用而基础的可视化图。个人认为通过画这几种基础图并调细节是很好的学可视化实践。
为了整体的美观和一致性,本文都用了一套自定义配色,通过mpl.rcParams["axes.prop_cycle"] = mpl.cycler('color', ['1EAFAE', 'A3FFFF', '69FFFF']) 语句实现简单改配色,具体关于mpl.rcParams后面再展开。
画散点图可以用两种主要的方法,scatter(x,y)和plot(x,y,'o') 。 通过ax.scatter(x,y)绘制以x为横坐标,y为纵坐标的散点图,scatter的重要参数如下:
ax.plot(x,y,'o')也可以画散点图,ax.plot()核心是绘制坐标系下的点和点之间的连线的,当突出点的大小而省略线时,就是散点图了,同样突出线就变成了折线图。通过fmt(也就是format_string)参数来控制这些,包括点的形状、颜色、线的风格颜色等。折线图基础绘制效果可回看上一部分可视化基础框架。
plot()的常用参数如下:
plot()除了plot(x,y,[fmt])这种写法之外,还可以传多套x,y以绘制多条折线,写法是plot(x,y,[fmt],x2,y2,[fmt2],…)。
另外plot()还支持plot('col1','col2',data=df)这种写法,这是对二维表格数据更友好的接口。本文讲到的其他图形如bar、barh等基本也都是支持ax.×××(df['x'],df['y']) 和ax.×××(x,y,data)写法的。
通过ax.bar(x,height)绘制柱状图,条形图的绘制用ax.barh(y,width),因bar和barh的用法很类似,参数之间有对应关系,这里结合着看。
注意的是柱状图绘制语句ax.bar(x,height)的返回值是一个容器(BarContainer),包含了所有画出来的柱。通过这个返回值可以对柱进行一些个性化的处理,另外的应用就是根据返回柱的属性给每个柱标上文本标签。
#给柱状图标上标签fig,ax= plt.subplots()rects=ax.bar(df['x'],df['y'])ax.set_ylim(0,100)for rect in rects: height = rect.get_height() ax.annotate('{}'.format(height), xy=(rect.get_x() + rect.get_width() / 2, height), xytext=(0,1), # 1 points vertical offset textcoords="offset points", ha='center', va='bottom')
通过给x以一定的偏移量,绘制簇状柱形图。代码如下:
#簇状柱 ClusterBarx = list(range(1,len(df)+1)) width = 0.2 #每个柱的宽度x1=[i-width for i in x]x2=[i+width for i in x]fig, ax = plt.subplots(figsize=(6,5))rects1 = ax.bar(x1,df['y'], width*2, label='Men',color='#1EAFAE')rects2 = ax.bar(x2,df['z'], width*2, label='Women',color='#69FFFF')ax.set_xticks(x)ax.set_xticklabels(df['x'])ax.legend()
通过给bottom参数传一个数组,可以画堆叠柱状图:堆叠柱除了等值堆叠之外,还可以等比堆叠,思路就是将每个x对应的柱都做一下数值变换,把柱的高度约束在[0,1],且堆叠之和为1,height=h[i]/sum(h)。
#堆叠柱状图fig,ax= plt.subplots()ax.bar(df['x'],df['y'],label='Men')ax.bar(df['x'],df['z'],bottom=df['y'],label='Women')ax.legend()#等比例堆叠柱fig,ax= plt.subplots()df['y1']=df.apply(lambda x:(x['y'])*100/(x['y']+x['z']),axis=1)df['z1']=df.apply(lambda x:(x['z'])*100/(x['y']+x['z']),axis=1)ax.bar(df['x'],df['y1'])ax.bar(df['x'],df['z1'],bottom=df['y1'])ax.set_ylim(0,100) #标签设置等代码省略
调节width参数使得柱和柱之间的宽度为0,并对数据进行统计在画图,可以用ax.bar()绘制直方图,但也不需要这么复杂,Matplotlib提供了绘制直方图的接口ax.hist(x,bins,normed),可以直接对某列数据绘制直方图。x是需要统计分布的数据列,bins控制分箱的个数,默认是10。
箱线图在数据分析中挺常用的,箱线图对于数据分布有很好的展示作用,Matplotlib提供了boxplot(x)用于绘制箱线图。
fig, ax= plt.subplots()ax.boxplot(df['y']) #箱线图
饼图是可视化中基础而重要的图形,是各种数据报告的常客,Matplotlib绘制饼图时因为xy轴默认比例尺不同,为了得到不扁的饼,需设置xy轴1像素对应的值相等。
#绘制饼图fig,ax=plt.subplots(subplot_kw=dict(aspect="equal")) ax.pie(df['y']) #为了得到不扁的饼,设置xy轴比例尺相同#---#环状图fig, ax = plt.subplots(subplot_kw=dict(aspect="equal")) wps=dict(width=0.3, edgecolor='w')ax.pie(df['y'], radius=1,startangle=90,counterclock=False,wedgeprops=wps)ax.pie(df['z'], radius=1-0.3,startangle=90,counterclock=False,wedgeprops=wps)
本文近五千字,从基础图表入手拆解对应绘制函数的重点参数,共10张图,基本都是个人绘制和排版的,个人认为较系统讲了Matplotlib的用法和核心功能,下篇会实践更有趣的内容。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。