数据可视化~pandas绘图(熊猫会画图?)

原文链接:http://www.juzicode.com/archives/3112

pandas为我们提供了容易上手使用的数据结构和数据分析工具,它的Series和DataFrame数据类型都有一个plot()方法,可以用于绘制常用图形。

1、线型图、基本绘图方法

构造Series时,传入的第1个位置参数对应坐标y的值,index参数对应坐标x的值,下面这个例子是一个正弦波曲线,x的取值从-2.0到2.0,间隔0.1;用pd.Series()构造了一个实例pdseries,使用pdseries.plot()方法可以绘制出默认kind=’line’形式的图形:

#juzicode.com
#vx:桔子code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

t = np.arange(-2.0, 2.0, 0.01)
s = np.sin(2 * np.pi * t)  
pdseries = pd.Series(s, index=t)
print(pdseries)
pdseries.plot()
plt.show()

和matplotlib一样,如果要正常显示中文,需要使用plt.rc()进行相应的设置,这里可以看到详细的设置方法:Python数据可视化~matplot默认配置修改(可解决中文、负号等显示问题)http://www.juzicode.com/archives/2421

#juzicode.com
#vx:桔子code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

plt.rc('font',family='Youyuan',size='11') #和matplotlib一样指明字体
plt.rc('axes',unicode_minus='False')

t = np.arange(-2.0, 2.0, 0.01)
s = np.sin(2 * np.pi * t)  
pdseries = pd.Series(s, index=t)
print(pdseries)
plt.title('sin(x) by桔子code') #设置中文标题
pdseries.plot()
plt.show()

更进一步的,可以参照pyplot.plot()方法设置曲线的类型、颜色等,可以参考这里:数据可视化~matplotlib基本绘图方法http://www.juzicode.com/archives/2455

#juzicode.com
#vx:桔子code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

plt.rc('font',family='Youyuan',size='11') #和matplotlib一样指明字体
plt.rc('axes',unicode_minus='False')

t = np.arange(-2.0, 2.0, 0.01)
s = np.sin(2 * np.pi * t)  
pdseries = pd.Series(s, index=t)
print(pdseries)
plt.title('sin(x) by桔子code') #设置中文标题
pdseries.plot(style='--g',grid=True,alpha=0.6,rot=30)#绿色虚线,显示grid,x轴旋转30度
plt.show()

如果要绘制DataFrame数据的某2列数据的线型图,传入x=’列标签名1’,y=’列标签名2′ 就能得到以列1为x轴,列2为y轴的线型图。如果没有指明x,x轴默认用index。

2、柱状图

使用plot(kind=’bar’)或者plot.bar()绘制柱状图,使用下面2种方法效果是一样的:

pdseries.plot(kind='bar', align='center',alpha=0.6,rot=50)#入参kind='bar'
pdseries.plot.bar(align='center',alpha=0.6,rot=50)

完整的例子:

#juzicode.com
#vx:桔子code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

plt.rc('font',family='Youyuan',size='11') #和matplotlib一样指明字体
plt.rc('axes',unicode_minus='False')

fruit = ('桔子', '橙子', '西瓜', '苹果', '香蕉', '西红柿')
weight = (100,135,50,83,92,66)
pdseries = pd.Series(weight, index=fruit)
print(pdseries)
plt.title('柱状图 by桔子code') #设置中文标题
pdseries.plot(kind='bar', align='center',alpha=0.6,rot=50)
#pdseries.plot.bar(align='center',alpha=0.6,rot=50)
plt.show()

3、水平柱状图

使用plot(kind=’barh’)或者plot.barh()绘制水平柱状图。rot参数设置x标签的旋转角度,alpha设置透明度,align设置对齐位置。

#juzicode.com
#vx:桔子code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

plt.rc('font',family='Youyuan',size='11') #和matplotlib一样指明字体
plt.rc('axes',unicode_minus='False')

fruit = ('桔子', '橙子', '西瓜', '苹果', '香蕉', '西红柿')
weight = (100,135,50,83,92,66)
pdseries = pd.Series(weight, index=fruit)
print(pdseries)
plt.title('柱状图 by桔子code') #设置中文标题
pdseries.plot(kind='barh', align='center',alpha=0.6,rot=0)
#pdseries.plot.barh(align='center',alpha=0.6,rot=0)
plt.show()

4、组合柱状图

前面的例子都是用Series构建的实例进行绘图,只有一列数据,如果要对DataFrame类型的数据绘图,可以使用bar方法绘制出组合柱状图。当然也可以用子图的方式,每列数据单独绘制一个子图,在后面绘制子图一节有介绍如何绘制子图。

#juzicode.com
#vx:桔子code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

plt.rc('font',family='Youyuan',size='11') #和matplotlib一样指明字体
plt.rc('axes',unicode_minus='False')

weight = np.random.rand(6,3)*100
fruit=['桔子', '橙子', '西瓜', '苹果', '香蕉', '西红柿']
attri = ['重量','体积','单价']
columns=pd.Index(attri,name='属性')
df = pd.DataFrame(weight,index=fruit,columns=columns)
print(df)
df.plot.bar(rot=0)
plt.title('组合柱状图 by桔子code')
plt.show()

使用stacked=True可以绘制堆叠形式的柱状图:

#juzicode.com
#vx:桔子code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

plt.rc('font',family='Youyuan',size='11') #和matplotlib一样指明字体
plt.rc('axes',unicode_minus='False')

weight = np.random.rand(6,3)*100
fruit=['桔子', '橙子', '西瓜', '苹果', '香蕉', '西红柿']
attri = ['重量','体积','单价']
columns=pd.Index(attri,name='属性')
df = pd.DataFrame(weight,index=fruit,columns=columns)
print(df)
df.plot.bar(rot=0,stacked=True) # stacked=True 
plt.title('组合柱状图 by桔子code')
plt.show()

5、饼图

使用plot(kind=’pie’)或者plot.pie()绘制饼图。

#juzicode.com
#vx:桔子code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

plt.rc('font',family='Youyuan',size='11') #和matplotlib一样指明字体
plt.rc('axes',unicode_minus='False')

weight = np.random.rand(6,3)*100
fruit=['桔子', '橙子', '西瓜', '苹果', '香蕉', '西红柿']
attri = ['重量','体积','单价']
columns=pd.Index(attri,name='属性')
df = pd.DataFrame(weight,index=fruit,columns=columns)
print(df)
df.plot.pie(subplots=True,labels=fruit,explode = [0.1, 0.2, 0, 0, 0, 0],figsize=(10,11), autopct="%.2f",shadow=True, startangle=0)
plt.title('饼图 by桔子code')
plt.show()

6、散点图

使用plot(kind=’scatter’)或者plot.scatter()方法绘制散点图,需要指明默认参数x和y的值,x和y是columns中选取的2个类型:

#juzicode.com
#vx:桔子code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

plt.rc('font',family='Youyuan',size='11') #和matplotlib一样指明字体
plt.rc('axes',unicode_minus='False')

weight = np.random.rand(6,3)*100
fruit=['桔子', '橙子', '西瓜', '苹果', '香蕉', '西红柿']
attri = ['重量','体积','单价']
columns=pd.Index(attri,name='属性')
df = pd.DataFrame(weight,index=fruit,columns=columns)
print(df)
df.plot.scatter(y='重量',x='单价') #默认参数x和y的值,x和y是columns中选取的2个类型
#df.plot(kind='scatter',y='重量',x='单价')  
plt.title('散点图 by桔子code')
plt.show()

7、直方图

使用plot(kind=’hist’)或者plot.hist()方法绘制直方图:

#juzicode.com
#vx:桔子code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

plt.rc('font',family='Youyuan',size='11') #和matplotlib一样指明字体
plt.rc('axes',unicode_minus='False')

weight = np.random.rand(6,3)*100
fruit=['桔子', '橙子', '西瓜', '苹果', '香蕉', '西红柿']
attri = ['重量','体积','单价']
columns=pd.Index(attri,name='属性')
df = pd.DataFrame(weight,index=fruit,columns=columns)
print(df)
df.plot.hist(bins=30 )  
plt.title('直方图 by桔子code')
plt.show()

8、箱体图

使用plot(kind=’box’)或者plot.box()方法绘制箱体图:

#juzicode.com
#vx:桔子code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

plt.rc('font',family='Youyuan',size='11') #和matplotlib一样指明字体
plt.rc('axes',unicode_minus='False')

weight = np.random.rand(6,3)*100
fruit=['桔子', '橙子', '西瓜', '苹果', '香蕉', '西红柿']
attri = ['重量','体积','单价']
columns=pd.Index(attri,name='属性')
df = pd.DataFrame(weight,index=fruit,columns=columns)
print('df=\n',df)
print('df.median=\n',df.median())
df.plot.box()  
plt.title('箱体图 by桔子code')
plt.show()
df=
 属性          重量         体积         单价
桔子   21.812787  94.465153  29.626212
橙子   63.506737  86.473310  56.866891
西瓜   29.594846  46.889638  85.091628
苹果   83.035897  17.606039  24.943117
香蕉   74.097714  34.420036  25.349002
西红柿  91.334128  85.335469  10.164941
df.median=
 属性
重量    68.802226
体积    66.112553
单价    27.487607
dtype: float64

9、面积图

使用plot(kind=’area’)或者plot.area()方法绘制面积图:

#juzicode.com
#vx:桔子code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

plt.rc('font',family='Youyuan',size='11') #和matplotlib一样指明字体
plt.rc('axes',unicode_minus='False')

weight = np.random.rand(6,3)*100
fruit=['桔子', '橙子', '西瓜', '苹果', '香蕉', '西红柿']
attri = ['重量','体积','单价']
columns=pd.Index(attri,name='属性')
df = pd.DataFrame(weight,index=fruit,columns=columns)
print('df=\n',df)
print('df.median=\n',df.median())
#df.plot.box()  
df.plot(kind='area')  
plt.title('面积图 by桔子code')
plt.show()

10、绘制子图

前面介绍的方法都是在一个图中显示多条曲线或者统计性图形,如果需要在一个画布中绘制多个子图,可以用到以下几种方法。

A、plot()传入subplots

在plot()方法中subplots=True,默认画出n行子图,下面的例子中有columns=[‘A1′,’B2′,’C3′,’D4′,’E4’] 5列数据,就会自动画出5个子图

#juzicode.com #vx:桔子code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rc('font',family='Youyuan',size='11') #和matplotlib一样指明字体
plt.rc('axes',unicode_minus='False')

t = np.arange(0, 10, 0.1)  #100行,用作index
s = np.random.randn(100,5) #100行5列的随机数据
df = pd.DataFrame(s, index=t,columns=['A1','B2','C3','D4','E4'])
df = df.cumsum() #累加
df.plot(title='随机曲线 by桔子code',subplots=True,figsize=(6,6))#subplots=True表明要分图绘制,同时figsize指明整个图片大小
plt.show()

回到前面组合柱状图的例子 ,我们也可以在多个子图中绘制柱状图:

#juzicode.com
#vx:桔子code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

plt.rc('font',family='Youyuan',size='11') #和matplotlib一样指明字体
plt.rc('axes',unicode_minus='False')

weight = np.random.rand(6,3)*100
fruit=['桔子', '橙子', '西瓜', '苹果', '香蕉', '西红柿']
attri = ['重量','体积','单价']
columns=pd.Index(attri,name='属性')
df = pd.DataFrame(weight,index=fruit,columns=columns)
print(df)
df.plot.bar(rot=0,subplots=True ,figsize=(8,8) )
plt.show()

B、plot()传入layout

传入subplots=True的基础上,​用layout=(m,n)指明子图的行列数,m*n的值要大于列的数值:

#juzicode.com #vx:桔子code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rc('font',family='Youyuan',size='11') #和matplotlib一样指明字体
plt.rc('axes',unicode_minus='False')

t = np.arange(0, 10, 0.1)  #100行,用作index
s = np.random.randn(100,5) #100行5列的随机数据
df = pd.DataFrame(s, index=t,columns=['A1','B2','C3','D4','E4'])
df = df.cumsum() #累加
df.plot(title='随机曲线 by桔子code',subplots=True,figsize=(9,9),layout=(3,3))#layout声明3行3列
plt.show()

C、plot()传入ax

首先用fig,axes=plt.subplots(m,n)生成m行n列的子图框,然后构造出和DataFrame相同列数的5个子图位置的列表,传入给ax入参。需要注意的时如果希望指定整幅图形的大小,要在plt.subplots()中声明figsize大小,这时候在df.plot()中声明的figsize无效。这时也需要设置subplots=True 。

#juzicode.com #vx:桔子code
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rc('font',family='Youyuan',size='11') #和matplotlib一样指明字体
plt.rc('axes',unicode_minus='False')
​
t = np.arange(0, 10, 0.1)  #100行,用作index
s = np.random.randn(100,5) #100行5列的随机数据
df = pd.DataFrame(s, index=t,columns=['A1','B2','C3','D4','E4'])
df = df.cumsum() #累加
​
fig,axes=plt.subplots(3,3,figsize=(10,10))
group = [axes[0][0], axes[0][2], axes[1][1], axes[2][0], axes[2][2]] #位置列表,元素个数为df列的数目
df.plot(title='随机曲线 by桔子code',subplots=True ,ax=group)#ax=group表示的位置,figsize=(15,15)无效
plt.show()

小结:今天桔子菌给大家介绍了pandas自带的绘图功能,文中的例子介绍了绘图的基本方法,还有更多的参数可以选择使用,更详细的参数设置可以参考官方文档。pandas绘图的基础仍然是matplotlib,熟练使用matplotlib后再使用pandas绘图就会融会贯通,反过来也一样,学会pandas的绘图方法再使用matplotlib绘图也会轻车熟路。

推荐阅读:
编码: 一个隐藏了30多年的bug,Windows含蓄说过某通不行?
zbar:给我来10G打码图片
用你的邮箱为你看家护院
好冷的Python-- if __name__==’__main__’是啥东东
Python混合编程:C语言接口ctypes(1)
数据可视化~matplotlib基本绘图方法
数据可视化~matplotlib显示多个子图 

发表评论

电子邮件地址不会被公开。 必填项已用*标注