matplotlib框架分为三层,这三层成了一个栈,上层调用下层。
【Backend后端层】
matplotlib API即位于该层,这些API用来在底层实现图形元素的一个个类:
(1)FigureCanvas对象实现了绘图区域这一概念;
(2)Renderer对象在FigureCanvas上绘图。
【美工层Artist】
图形中所有能看见的元素都属于Artist对象,即标题、轴标签、刻度等组成图形的所有元素都是Artist对象的实例。
(1)Figure:指整个图形,包括所有的元素,比如标题;
(2)Axes坐标系:数据的绘图区域;
(3)Axis坐标轴:坐标系中的一条轴,包含大小限制、刻度和刻度标签。
特点为:
(1)一个figure图可以包含多个axes坐标系,但是一个axes只能属于一个figure。
(2)一个axes坐标系可以包含多个axis坐标轴,包含两个即2d坐标系,3个即3d坐标系。
【Scripting层】
主要用于数据分析和可视化,pyplot:
(1)操作或者改动Figure对象,例如创建Figure对象;
(2)大部分工作是处理样本的图形与坐标的生成。
【创建子图方式一】先建立子图然后再填充图表
import matplotlib.pyplot as plt
import numpy as np
# 创建子图方式1:先建立子图然后再填充图表
fig = plt.figure(facecolor='gray')
ax1 = fig.add_subplot(2,2,1) # 表示创建一个2行2列的图,左上
plt.plot(np.random.rand(50).cumsum(),'k--')
plt.plot(np.random.rand(50).cumsum(),'b--')
ax2 = fig.add_subplot(2,2,2)
ax2.hist(np.random.rand(50),alpha=0.5)
plt.show()
【创建子图方式二】 创建一个新的figure,并返回一个subplot对象的numpy数组。
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# 创建子图方式2(推荐):创建一个新的figure,并返回一个subplot对象的numpy数组 plt.subplot
# sharex 和sharey 表示是否共享x或y刻度
fig,axes = plt.subplots(2,3,figsize =(10,4),sharex=True,sharey=True) # axes就是numpy.ndarray
ts = pd.Series(np.random.randn(1000).cumsum())
print(axes,axes.shape,type(axes))
# 生成图表对象的数组
ax1 = axes[0,1]
ax1.plot(ts)
plt.show()
线条和标记节点样式: 标记字符:标记线条中的点。
(1)线条颜色,color='g';
(2)线条风格,linestyle='--';
(3)线条粗细,linewidth=5.0;
(4)标记风格,marker='o';
(5)标记颜色,markerfacecolor='b';
(6)标记尺寸,markersize=20;
(7)透明度,alpha=0.5;
线条和标记节点格式字符 如果不设置颜色,系统默认会取一个不同颜色来区别线条。
颜色字符(color) |
风格(linestyle) |
标记字符(mark) |
r红色 |
-实线 |
o实心圈标记 |
g绿色 |
--虚线,破折线 |
.点标记 |
b蓝色 |
-. 点划线 |
,像素标记,极小的点 |
w白色 |
:点虚线 |
v倒立三角标记 |
c青色 |
“留空或空格,无线条 |
^上三角标记 |
m洋红 |
|
> 右三角标记 |
y黄色 |
|
< 左三角标记 |
k黑色 |
|
* 星形标记 |
#00ff00 16进制 |
|
+ 十字标记 |
import matplotlib.pyplot as plt
from matplotlib import font_manager # 设置中文显示
import random
# 先生成fig
plt.figure(figsize=(20,8))
# 这个字体设置为全局设置,只用在该处修改即可
my_font = font_manager.FontProperties(fname=f"C:\Windows\Fonts\simsun.ttc",size=20)
# 准备数据,折线图点,x,y坐标个数--对应
x = range(60)
x_ch =["11点{}分".format(i) for i in x]
y =[random.uniform(15,18) for i in range(60)]
y_ticks = range(40)
plt.plot(x,y)
# 修改刻度值
# 指定显示的x刻度的列表,第二参数指定跟第一个参数对应的中文
plt.xticks(x[::5],x_ch[::5],rotation=45,fontproperties=my_font) # rotation表示旋转角度,fontproperties指定中文字体
plt.yticks(y_ticks[::5])
plt.xlabel("时间",fontproperties=my_font)
plt.ylabel("温度",fontproperties=my_font)
plt.title("上海城市11点到12点之间的温度",fontproperties=my_font)
# plt.savefig("test.png")
# 显示调用show()
plt.show()
matplotlib.pyplot.subplots(nrows=1, ncols=1, **fig_kw) # 创建一个带多坐标系的图
通过subplots函数实现(旧版本中有subplot,使用起来不方便),推荐使用subplots。
返回值为:fig图对象和ax
其中ax:设置标题等方法不同:
(1)set_xticks:
(2)set_yticks:
(3)set_xlabel:
(4)set_ylabel:
import matplotlib.pyplot as plt
from matplotlib import font_manager # 设置中文显示
import random
# 当在多个ax里面画图的时候,刻度、标签在相应的坐标系里面指定
# 这个字体设置为全局设置,只用在该处修改即可
my_font = font_manager.FontProperties(fname=f"C:\Windows\Fonts\simsun.ttc",size=20)
#两个城市的温度,在多个坐标系中显示
fig,ax = plt.subplots(nrows=1,ncols=2,figsize=(20,8)) #也就是一行2列
# 准备数据,折线图点,x,y坐标个数--对应
x = range(60)
x_ch =["11点{}分".format(i) for i in x]
y_shanghai = [random.uniform(15,18) for i in range(60)]
y_beijing = [random.uniform(15,18) for i in range(60)]
y_ticks = range(40)
# 显示上海
ax[0].plot(x,y_shanghai,label='上海')
ax[1].plot(x,y_beijing,color='r',linestyle='--',label='北京')
# 修改刻度值
# plt是对整体画图,ax对于每个坐标系处理
ax[0].set_xticks(x[::5],x_ch[::5])
ax[1].set_xticks(x[::5],x_ch[::5])
#
ax[0].set_yticks(y_ticks[::5])
ax[1].set_yticks(y_ticks[::5])
# 增加标题 坐标描述
ax[0].set_xlabel("时间",fontproperties=my_font)
ax[0].set_ylabel("温度",fontproperties=my_font)
ax[0].set_title("上海11点到12点之间的温度",fontproperties=my_font)
ax[1].set_xlabel("时间",fontproperties=my_font)
ax[1].set_ylabel("温度",fontproperties=my_font)
ax[1].set_title("北京11点到12点之间的温度",fontproperties=my_font)
#增加图例
plt.legend(loc='best')
# plt.savefig("test.png")
# 显示调用show()
plt.show()
【api说明】
plt.bar(x, height, width=0.8, align='center', **kwargs)
width柱状图的宽度
align对其方式:center、edge、
**kwargs参数有颜色color,b,r,g,y,c,m,k,g
【案例一】
'''
plt.bar(x, height, width=0.8, align='center', **kwargs)
width柱状图的宽度
align对其方式:center、edge、
**kwargs参数有颜色color,b,r,g,y,c,m,k,g
'''
my_font = font_manager.FontProperties(fname=f'./simsun.ttc',size=12)
plt.figure(figsize=(20,8),dpi=80)
movie_name=['雷神3','正义联盟','东方快车谋杀案','寻梦环游记','全球风暴','降魔传','追捕','七十七天','密战','狂兽','其他']
y =[78853,57767,22354,15969,14839,8725,8716,8318,7916,6764,5222]
x = range(len(movie_name))
plt.bar(x,y,width=0.5,color=['b','r','g','y','c','m','y','k','c','g','g'])
#修改刻度,
plt.xticks(x,movie_name,fontproperties=my_font)
plt.show()
import matplotlib.pyplot as plt
from matplotlib import font_manager
my_font = font_manager.FontProperties(fname=f'./simsun.ttc',size=12)
plt.figure(figsize=(20,8),dpi=80)
movie_name=['雷神3','正义联盟','寻梦环游记']
first_day=[10587,10062,52175]
first_weekend=[46224,934479,611830]
x = range(len(movie_name))
plt.bar(x,first_day,width=0.2,label='首日')
plt.bar([(i+0.2)for i in x],first_weekend,width=0.2,label='首周')
plt.legend(loc='best')
#修改刻度,
plt.xticks([(i+0.1)for i in x],movie_name,fontproperties=my_font)
plt.show()
【案例三】
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.figure(figsize=(10,4))
x = np.arange(10)
y1 = np.random.rand(10)
y2 = np.random.rand(10)
#width表示宽度比例
# facecolor柱状图里填充的颜色,edgecolor是边框的颜色
# left每个柱x轴左边界,bottom每个柱y轴下边界--> bottom扩展即可画甘特图 gantt chart
# align 决定整个bar图分布,默认left表示默认从左边界开始绘制,center会将图绘制在中间位置
# xerr/yerr:x/y表示方向error bar
plt.bar(x,y1,width=1,facecolor='yellowgreen',edgecolor='white',yerr=y1*0.1)
plt.bar(x,y2,width=1,facecolor='lightskyblue',edgecolor='white',yerr=y2*0.1)
plt.show()
【案例四:多列柱状图】
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
fig,axes = plt.subplots(4,1,figsize=(10,10))
s = pd.Series(np.random.randint(0,10,16),index=list('abcdefghijklmnop'))
df = pd.DataFrame(np.random.rand(10,3),columns=['a','b','c'])
#单系列
s.plot(kind='bar',ax=axes[0])
# 多系列 柱状图
df.plot(kind='bar',ax=axes[1])
# 多系列 堆叠图
df.plot(kind='bar',ax=axes[2],stacked=True)
plt.show()
【相关概念】
组数:在统计数据时,我们把数据按照不同的范围分成几个组,分成的组的个数称为组数;
组距bins:每一个组两个端点的差;
mormed:bool或optional以频率显示,默认频数值1为频率。
设置组数(通常对于数据较少的情况,分为5~12组,数据较多,更换图形显示方式),
通常设置组数公式为:组数 = 极差/组距 = (max-min)/bins
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
fig,axes = plt.subplots(2,1,figsize=(8,6))
df1 = pd.DataFrame(np.random.rand(10,4),columns=['a','b','c','d'])
df2 = pd.DataFrame(np.random.rand(10,4),columns=['a','b','c','d'])
# stacked参数表示堆叠,默认情况下,区域图被堆叠
# 为了产生堆面积图,每列必须是正值或全部负值。
# 当数据有Nan时候,自动填充0,所以图标签需要清洗掉缺失值
df1.plot.area(colormap='Greens_r',alpha=0.5,ax=axes[0])
df1.plot.area(stacked=False,colormap='Set2',alpha=0.5,ax=axes[1])
plt.show()
极坐标图:调用subplot()创建子图时设置projection='polar',便可创建一个极坐标子图,然后调用plot()在极坐标子图中绘图。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import font_manager
'''
极坐标图:调用subplot()创建子图时设置projection='polar',便可创建一个极坐标子图,然后调用plot()在极坐标子图中绘图
'''
# 创建极坐标轴
s = pd.Series(np.arange(20))
theta = np.arange(0,2*np.pi,0.02)
print(s.head())
print(theta[:10])
# 创建数据
fig = plt.figure(figsize=(8,4),dpi=80)
ax1 = plt.subplot(121,projection='polar')
ax2 = plt.subplot(122)
# 创建极坐标子图
# 还可以写:ax = fig.add_subplot(111,polar=True)
ax1.plot(theta,theta*3,linestyle='--',lw=1)
ax1.plot(s,linestyle='--',marker='.',lw=2)
ax2.plot(theta,theta*3,linestyle='--',lw=1)
ax2.plot(s)
plt.grid()
# 创建极坐标图,参数1为角度(弧度制),参数2为value
#lw参数是线宽
plt.show()