pandas的plot函数已经可以满足很多的基本作图需求,但是其有一个比较明显缺点是不能一次性的在同一个坐标轴中画不同类型的图,比如折线图和柱状图,而且也不能设置坐标轴刻度的格式。当然这两个需求在matplotlib中是很容易就可以实现的,毕竟pandas的plot函数也是基于matplotlib的,而且matplotlib本身相对于其他的一些画图库,其也是较为底层和功能强大的。
先直接看代码和得到的结果图:
import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.ticker import FuncFormatter
import numpy as np
df=pd.DataFrame(np.arange(12).reshape(4,3),columns=['aaa','bbb','c'])
df['c']=100000000*np.random.rand(len(df))
fig,ax=plt.subplots(1,1,figsize=(9,6))
ax1=ax.twinx()
@FuncFormatter
def format(x,pos):
return '%d'%x
ax.yaxis.set_major_formatter(format)
ax1.yaxis.set_major_formatter(format)
df['c'].plot(ax=ax1,figsize=(9,6),style=['g-'])
ax1.legend(('helloworld',),loc='upper center')
df[['aaa','bbb']].plot(kind='bar',grid=True,ax=ax,figsize=(9,7)) #柱状图应该在折线图之后画,防止因为折线图所需要的坐标轴面积更小而让柱状图结果显示不全
ax.plot(df.index,[1,2,3,4])
ax.legend(('new','aaa','bbb'))
下面对每个部分分别说明。
1、双Y轴
这个很简单,直接新建一个共享x轴的孪生坐标轴,看ax1=ax.twinx()语句,然后直接在ax1坐标轴上进行画图就会展示第二个Y轴。
2、同一坐标轴中画不同类型的图
这个其实更简单,由于已经有了ax坐标轴对象,我们只需要调用ax对象的plot方法画图即可,plot方法画的是折线图,对于柱状图,可以调用ax对象的bar方法,然后类似的,对于其他类型的图,只需要调用相应的画图方法即可。本例子中,是直接利用DataFrame的plot函数实现的,因为这个函数直接实现了通过设定参数实现不同类型的图,但是一次只能设置一种类型,不能一下次通过对不同的列设置不同的类型,但是实际上可以分开多个语句,即对不同的类型分开单独的语句进行类型的设置,只要保证在同一个ax坐标轴对象上作图即可实现。参考关于ax对象的文档。
3、设置坐标轴刻度格式
这个需要用到matplotlib.ticker.FuncFormatter,先按本例代码的方式导入,然后可以通过装饰器语法,在新建的装饰函数中设定格式,比如本例中设定的格式就是'%d',表示按整数的格式显示,而不是按默认的科学计数法显示;之后再通过ax.yaxis.set_major_formatter(format)方法将装饰器函数作为参数传入,实现格式的设定。
注意点:
最后讲一下本例中需要注意的点:
1、画柱状图的plot语句应该在画折线图的plot语句之后,即应该先画折线图后画柱状图,如果先画柱状图,由于折线图所需的区域更小,后面的折线图的坐标轴的边界会覆盖原来的柱状图的坐标轴边界,从而导致柱状图显示不全,如下图所示,最右边的橙色的矩形便被覆盖掉了,导致显示不全。
2、在设置legend是,传入的图例参数应该是以元组的形式传入,而不能直接以一个字符串的形式传入,因为legend函数默认该参数为一个可迭代对象,如果直接是一个字符串,则只会显示第一个字符,因为arg[0]只截取字符串参数arg的第一个字符。