3.7 matplotlib库
目录
数据可视化有助于深度理解数据。
本节介绍绘制图形的基本方法。
1. matplotlib库简介
1.1 matplotlib库概述
matplotlib是Python优秀的数据可视化第三方库,是一个非常强大的Python画图工具。它是Python的2D绘图库,可以以各种硬拷贝格式和跨平台的交互式环境生成出版质量级别的图形,能绘制线图、散点图、等高线图、条形图、柱状图、3D 图形、甚至是图形动画等等。通过学习matplotlib库,可以掌握表示、清洗、统计和展示数据的能力。
1.2 matplotlib库的效果
1.3 matplotlib库的安装和引用
Anaconda里面已经安装matplotlib。
在原生Python中安装,在控制台中输入:
pip install matplotlib
matplotlib库由各种可视化类构成,内部结构复杂,受Matlab启发,matplotlib.pyplot是绘制各类可视化图形的命令子库,相当于快捷方式。
安装之后通过以下方法导入:
#plt为约定俗成的matplotlib.pyplot引用别名
import matplotlib.pyplot as plt
1.4 matplotlib库小试
使用 matplotlib 的 scatter 方法绘制散点图。
# 使用 matplotlib 的 scatter 方法绘制散点图
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [2.3, 3.4, 1.2, 6.6, 7.0]
plt.scatter(x, y,color='r', marker='+')
# plt.show()
运行结果:
**特别说明:**代码中plt.show()用于显示图形,在Jupyter Notebook中,即使没有plt.show(),图形也会显示出来,但为了使代码也适用于其他编辑器,课件程序将予以保留。
2. pyplot的plot函数
2.1 plot函数的调用
语法:plt.plot(x, y, format_string, **kwargs)
- x : X轴数据,列表或数组,可选
- y : Y轴数据,列表或数组
- format_string: 控制曲线的格式字符串,可选
- **kwargs : 第二组或更多(x,y,format_string)
- 当绘制多条曲线时,各条曲线的x不能省略
import numpy as np
a = np.arange(10)
plt.plot(a,2*a,a,3*a,a,4*a,a,5*a)
# plt.show()
运行结果:
format_string: 控制曲线的格式字符串可选,由颜色字符、风格字符和标记字符组成:
颜色字符 | 说明 |
---|---|
‘b’ | 蓝色 |
‘g’ | 绿色 |
‘r’ | 红色 |
‘y’ | 黄色 |
‘k’ | 黑色 |
‘w’ | 白色 |
‘c’ | 青绿色cyan |
‘m’ | 洋红色magenta |
‘#008000’ | RGB某颜色 |
‘0.8’ | 灰度值字符串 |
风格字符 | 说明 |
---|---|
‘‐’ | 实线 |
‘‐‐’ | 破折线 |
‘‐.’ | 点划线 |
‘:’ | 虚线 |
‘’ ‘’ | 无线条 |
标记字符 | 说明 |
---|---|
‘.’ | 点标记 |
‘,’ | 像素标记(极小点) |
‘o’ | 实心圈标记 |
‘v’ | 倒三角标记 |
‘^’ | 上三角标记 |
‘>’ | 右三角标记 |
‘<’ | 左三角标记 |
‘1’ | 下花三角标记 |
‘2’ | 上花三角标记 |
‘3’ | 左花三角标记 |
‘4’ | 右花三角标记 |
‘s’ | 实心方形标记 |
‘p’ | 实心五角标记 |
‘*’ | 星形标记 |
‘h’ | 竖六边形标记 |
‘H’ | 横六边形标记 |
‘+’ | 十字标记 |
‘x’ | x标记 |
‘D’ | 菱形标记 |
‘d’ | 瘦菱形标记 |
‘|’ | 垂直线标记 |
颜色字符、风格字符和标记字符可以组合使用。
import numpy as np
a = np.arange(10)
plt.plot(a,2*a,'g-o',a,3*a,'rx:',a,4*a,'*m',a,5*a,'b-.')
# plt.show()
运行结果:
plot函数的第二种调用方式:用命名参数传递参数
**kwargs : 第二组或更多(x,y,format_string)
color : 控制颜色, color=‘green’
linewidth:线宽, linewidth=2
linestyle : 线条风格, linestyle=‘dashed’
marker : 标记风格, marker=‘o’
markerfacecolor: 标记颜色, markerfacecolor=‘blue’
markersize : 标记尺寸, markersize=20
import numpy as np
a = np.arange(10)
plt.plot(a,3*a,color='cyan',linewidth=8, linestyle='-',marker='*',markerfacecolor='b',markersize=30)
plt.plot(a,2*a,color='beige',linewidth=5, linestyle='dashed',marker='*',markerfacecolor='r',markersize=20)
plt.show()
输出结果:
2.2 控制中文显示
方法一:pyplot不默认支持中文显示,需要用rcParams修改字体来实现。
import matplotlib.pyplot as plt
import matplotlib
matplotlib.rcParams['font.family']='SimHei'
plt.plot([1,3,5,7,6,4,2])
plt.ylabel("这是纵轴")
# plt.show()
运行结果:
属性 | 说明 |
---|---|
‘font.family’ | 用于显示字体的名字 |
‘font.style’ | 字体风格,正常’normal’或斜体’italic’ |
‘font.size’ | 字体大小,整数字号或者’large’、‘x‐small’ |
中文字体 | 说明 |
---|---|
‘SimHei’ | 中文黑体 |
‘Kaiti’ | 中文楷体 |
‘LiSu’ | 中文隶书 |
‘FangSong’ | 中文仿宋 |
‘YouYuan’ | 中文幼圆 |
‘STSong’ | 华文宋体 |
import numpy as np
matplotlib.rcParams['font.family']='SimHei'
matplotlib.rcParams['font.size']=20
x = np.linspace(-4*np.pi,4*np.pi,2000)
plt.xlabel("横轴:X值")
plt.ylabel("纵轴:正弦值")
plt.plot(x,np.sin(x),'r:')
# plt.show()
运行结果:
修改rcParams改变的是全局字体,留有隐患,建议用方法二:在有中文输出的地方,增加一个属性:fontproperties。
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-4*np.pi,4*np.pi,2000)
plt.xlabel("横轴:X值", fontproperties = 'Kaiti', fontsize = 30)
plt.ylabel("纵轴:正弦值", fontproperties = 'Kaiti', fontsize = 30)
plt.plot(x,np.sin(x),'b:')
# plt.show()
运行结果:
2.3 pyplot的文本显示
函数 | 说明 |
---|---|
plt.xlabel() | 对X轴增加文本标签 |
plt.ylabel() | 对Y轴增加文本标签 |
plt.title() | 对图形整体增加文本标签 |
plt.text() | 在任意位置增加文本 |
plt.annotate() | 在图形中增加带箭头的注解 |
x = np.linspace(-4*np.pi,4*np.pi,2000)
plt.plot(x,np.sin(x),'r--')
plt.xlabel("横轴:X值", fontproperties = 'Kaiti', fontsize = 30, color='violet')
plt.ylabel("纵轴:正弦值", fontproperties = 'Kaiti', fontsize = 30, color='violet')
plt.title('正弦值曲线$y=sin(2\pi x)$',fontproperties = 'SimHei', fontsize = 30, color='c')
plt.text(np.pi/2,0,'$sin(\pi/2)=0$',fontsize=20)
plt.grid(True)
# plt.show()
运行结果:
2.4 pyploy的子绘图区域
语法格式:plt.subplot2grid(GridSpec, CurSpec, colspan=1, rowspan=1)
基本思想:设定网格,选中网格,确定选中行列区域数量,编号从0开始
plt.subplot2grid((3,3), (1,0), colspan=2)
plt.subplot2grid((3,3), (0,0), colspan=3)
plt.subplot2grid((3,3), (1,0), colspan=2)
plt.subplot2grid((3,3), (1,2), rowspan=3)
plt.subplot2grid((3,3), (2,0))
plt.subplot2grid((3,3), (2,1))
3. matplotlib基础绘图函数示例
3.1 基础图标函数
函数 | 说明 |
---|---|
plt.plot(x,y,fmt,…) | 绘制坐标图 |
plt.scatter(x,y) | 绘制散点图 |
plt.pie(data,explode) | 绘制饼图 |
plt.hist(x,bins,normed) | 绘制直方图 |
plt.contour(X,Y,Z,N) | 绘制等高线图 |
plt.boxplot(data,notch,position) | 绘制箱形图 |
plt.bar(left,height,width,bottom) | 绘制条形图 |
plt.barh(width,bottom,left,height) | 绘制横向条形图 |
plt.polar(theta,r) | 绘制极坐标图 |
plt.psd(x,NFFT=256,pad_to,Fs) | 绘制功率谱密度图 |
plt.specgram(x,NFFT=256,pad_to,F) | 绘制谱图 |
plt.cohere(x,y,NFFT=256,Fs) | 绘制X‐Y的相关性函数 |
plt.step(x,y,where) | 绘制步阶图 |
plt.vlines() | 绘制垂直图 |
plt.stem(x,y,linefmt,markerfmt) | 绘制柴火图 |
plt.plot_date() | 绘制数据日期 |
3.2 pyplot饼图的绘制
plt.pie()
import matplotlib.pyplot as plt
labels = 'First', 'Second', 'Third', 'fourth'
sizes = [15,25,30,30]
explode = [.1,0,0,0]
plt.pie(sizes,explode=explode,labels=labels,autopct='%1.1f%%',shadow=False,startangle=90)
plt.axis('equal')
plt.show()
运行结果:
3.3 pyplot直方图的绘制
plt.hist()
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(0)
mu,sigma = 100,20
a = np.random.normal(mu,sigma,size=100)
plt.hist(a,20,histtype='stepfilled', facecolor='b',alpha=.75)
plt.title('Histogram')
plt.show()
运行结果:
3.4 pyplot散点图的绘制
# 面向对象绘制散点图
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot(10*np.random.randn(100),10*np.random.randn(100),'o')
ax.set_title('Scatter')
# plt.show()
运行结果:
3.5 绘制二维图形示例
绘制折线图
import numpy as np
import matplotlib.pyplot as plt
# 创建数据
np.random.seed(1) # 固定随机数
x = np.arange(10)
y = np.random.rand(10)
# 显示图形
plt.plot(x, y) # 创建折线图
plt.show()
运行结果:
接下来绘制
f
(
x
)
=
(
x
−
2
)
x
(
x
+
2
)
f(x)=(x-2)x(x+2)
f(x)=(x−2)x(x+2)图形。虽然我们可以看出在
x
x
x为-2、0、2时,
f
(
x
)
f(x)
f(x)为0,但只有绘制了图形,才能知道它整体上是什么形状。
首先定义函数 f ( x ) f(x) f(x)。
import numpy as np
import matplotlib.pyplot as plt
def f(x):
return (x - 2) * x * (x + 2)
定义完毕后,把数值代入这个函数中的x。运行如下代码,即可获取对应的返回值f。
print(f(1))
#输出-3
即使x为ndarray数组,程序也会一次性地以ndarray类型返回与各个元素对应的f。
print(f(np.array([1, 2, 3])))
#输出:[-3 0 15]
下面定义绘制图形的范围,令x的范围为从-3到3,并定义在此范围内计算的x的间隔为0.5。
x = np.arange(-3, 4.5, 0.5)
print(x)
#输出:[-3. -2.5 -2. -1.5 -1. -0.5 0. 0.5 1. 1.5 2. 2.5 3. 3.5 4. ]
请注意,如果写成np.arange(-3, 3, 0.5),则输出的结果到2.5为止,所以这里写成了np.arange(-3, 4.5, 0.5),代码中的数值比3大。
但在定义图形中的x时,linspace函数也许比arange更加方便。可以写成linspace(n1, n2, n),运行之后,程序将返回n个在n1和n2之间等间隔分布的点。
x = np.linspace(-3, 3, 10)
print(np.round(x, 2))
#输出:[-3. -2.33 -1.67 -1. -0.33 0.33 1. 1.67 2.33 3. ]
print语句中的np.round(x, n)是将x四舍五入为保留小数点后n位的数值的函数。
绘制图形
plt.plot(x, f(x))
# plt.show()
输出结果:
装饰图形
当函数的系数发生变化时,图形会如何变化。对函数稍加调整,通过下面的代码再次绘制这个函数的图形。
# 定义函数
def f2(x, w):
return (x - w) * x * (x + 2) #(A) 函数的定义
# 定义 x
x = np.linspace(-3, 3, 100) # (B) 把 x 分为 100 份
# 绘制图形
plt.plot(x, f2(x, 2), color='black', label='$w=2$') # (C)
plt.plot(x, f2(x, 1), color='cornflowerblue',
label='$w=1$') # (D)
plt.legend(loc="upper left") # (E) 显示图例
plt.ylim(-15, 15) # (F) y 轴的范围
plt.title('$f_2(x)$') # (G) 标题
plt.xlabel('$x$') # (H) x 标签
plt.ylabel('$y$') # (I) y 标签
plt.grid(True) # (J) 网格线
plt.show()
输出结果:
图形变得很平滑,其中还加入了网格线、标签、标题和图例。可以清晰地看到,函数
f
(
x
)
=
(
x
−
2
)
x
(
x
+
2
)
f(x)=(x-2)x(x+2)
f(x)=(x−2)x(x+2)与x轴的交点为-2、0、2(黑线:w=2)。还可以看到,当w=1,即
f
(
x
)
=
(
x
−
1
)
x
(
x
+
2
)
f(x)=(x-1)x(x+2)
f(x)=(x−1)x(x+2)时,函数与x轴的交点为-2、0、1(蓝线:w=1)。
以上代码在开头(A)处定义了函数f2(x, w)。除了变量x之外,这个函数的参数还有w。改变w就可以改变f2的形状。
接下来定义要计算的数据点x,这次把x分为100份((B))。图形用plt.plot表示的,通过添加“color=‘颜色名’”,可以指定图形中线条的颜色。black表黑色(©),cornflowerblue表示浅蓝色((D))。
可以通过以下代码来查看能够使用的颜色。
import matplotlib
# print(matplotlib.colors.cnames)
基本色可以仅用一个字母来指定,r代表红色,b代表蓝色,g代表绿色,c代表蓝绿色,m代表品红色,y代表黄色,k代表黑色,w代表白色。还可以像color=(255, 0, 0)这样,使用元素为0-255的整数的tuple类型的值自由地指定RGB。
在代码的输出中,图形左上角显示了图例,这是通过代码的©和(D)中的plot的“label=‘字符串’”指定的,(E)中的plt.legend()用于显示图例。图例的位置可以自动设定,也可以使用loc指定。在指定位置时,upper right代表右上角,upper left代表左上角,lower left代表左下角,lower right代表右下角。
y轴的显示范围可以用plt.ylim(n1, n2)指定为从n1到n2((F))。同样,x轴的范围使用plt.xlim(n1, n2)指定。图形标题使用plt.title(‘字符串’)((G))指定。x轴与y轴的标签分别用plt.xlabel(‘字符串’)((H))和plt.ylabel(‘字符串’)((I))指定。plt.grid(True)用于显示网格线((J))。可以将table和title的字符串指定为用“$”括起来的tex形式的表达式,这样就可以显示美观的数学式了。
并列显示多张图形的另一种方法:
如果想并列显示多张图形,可以像如下代码来使用plt.subplot(n1, n2, n)(©)。可以指定图形的绘制位置——把一个整体分割成纵向n1份、横向n2份的格子之后的第n个区域。区域的编号方式是:从左上角开始是1号,它的右边是2号,以此类推,当到达最右边之后,就从下一行的左边开始继续编号。请注意plt.subplot中的n,它比较特别,不是从0开始的,而是从1开始的,如果令n为0,就会出现错误。
plt.figure(figsize=(10, 3)) # (A) 指定figure
plt.subplots_adjust(wspace=0.5, hspace=0.5) # (B) 指定图形间隔
for i in range(6):
plt.subplot(2, 3, i + 1) # (C) 指定图形的绘制位置
plt.title(i + 1)
plt.plot(x, f2(x, i), 'k')
plt.ylim(-20, 20)
plt.grid(True)
plt.show()
输出结果:
代码清单3-2-(9)中(A)处的plt.figure(figsize=(w, h))用于指定整个绘制区域的大小。绘制区域的宽度为w,高度为h,当使用subplot并列显示时,可以通过(B)处的plt.subplots_adjust(wspace=w, hspace=h)调节两个相邻区域的横向间隔与纵向间隔。w为横向间隔,h为纵向间隔,它们的数值越大,间隔越大。
3.6 绘制三维图形
包含两个变量的函数
如何绘制包含两个变量的函数的图形?比如函数:
f ( x 0 , x 1 ) = ( 2 x 0 2 + x 1 2 ) e x p ( − ( 2 x 0 2 + x 1 2 ) ) (4.4-1) f(x_0,x_1)=(2x_0^2+x_1^2)exp(-(2x_0^2+x_1^2)) \tag{4.4-1} f(x0,x1)=(2x02+x12)exp(−(2x02+x12))(4.4-1)
首先,在如下代码中将上面的函数定义为f3。然后,计算当x0和x1取不同的值时,f3的值是多少。
import numpy as np
import matplotlib.pyplot as plt
# 定义函数 f3
def f3(x0, x1):
ans = (2 * x0**2 + x1**2) * np.exp(-(2 * x0**2 + x1**2))
return ans
# 根据 x0 和 x1 计算 f3
xn = 9
x0 = np.linspace(-2, 2, xn) # (A)
x1 = np.linspace(-2, 2, xn) # (B)
y = np.zeros((len(x0), len(x1))) # (C)
for i0 in range(xn):
for i1 in range(xn):
y[i1, i0] = f3(x0[i0], x1[i1]) # (D)
(A)定义了要计算的x0的范围。由于xn=9,所以运行下面的命令可知,x0是由9个元素构成的,x1和x0相同((B))。
print(x0)
#输出:[-2. -1.5 -1. -0.5 0. 0.5 1. 1.5 2. ]
通过©处的代码准备一个用于存放计算结果的二维数组变量y,然后在(D)处,根据由x0和x1定义的棋盘上的各个点求f3,并将结果保存在y[i1, i0]中。请注意这里的元素索引,用于指示x1的内容的i1在前,i0在后。这是为了与后面的显示方向相对应。
下面通过round函数,把矩阵y四舍五入到小数点后1位(为了便于查看),并输出矩阵。
print(np.round(y, 1))
输出结果:
仔细看一下矩阵中的数值会发现,矩阵的中心和周围都是0,其它地方数值较高。但是,只看数值,很难想象出函数的形状。
接下来介绍绘制三维立体图形的方法,即使用surface。
from mpl_toolkits.mplot3d import Axes3D # (A)
xx0, xx1 = np.meshgrid(x0, x1) # (B)
plt.figure(figsize=(5, 4.5))
ax = plt.subplot(1, 1, 1, projection='3d') # (C)
ax.plot_surface(xx0, xx1, y, rstride=1, cstride=1, alpha=0.3,
color='blue', edgecolor='black') # (D)
ax.set_zticks((0, 0.2)) # (E)
ax.view_init(75, -95) # (F)
# plt.show()
输出结果:
绘制三维图形前,需要导入mpl_toolkits.mplot3d的Axes3D。
然后,根据坐标点x0、x1生成xx0、xx1。
下面确认一下变量x0、x1的内容。
print(x0)
print(x1)
#输出结果:
#[-2. -1.5 -1. -0.5 0. 0.5 1. 1.5 2. ]
#[-2. -1.5 -1. -0.5 0. 0.5 1. 1.5 2. ]
通过np.meshgrid(x0, x1)生成的xx0是如下所示的二维数组。
print(xx0)
输出结果:
xx1是如下所示的二维数组。
print(xx0)
print(xx1)
输出结果:
xx0和xx1是与y一样大的矩阵,当输入xx0[i1, i0]和xx1[i1, i0]时,f3为y[i1, i0]。
为了在三维坐标系中绘制图形,在声明subplot时指定了projection=‘3d’(代码清单中的©)。然后,把表示这个图形的id的返回值保存在ax中。这段代码只在figure中指定了一个subplot,但实际上也可以像subplot(n1, n2, n,project=‘3d’)这样指定多个坐标系。
代码清单(D)中的ax.plot_surface(xx0, xx1, y)用于显示surface。可以把自然数赋给可选项rstride与cstride,来指定纵轴与横轴每隔几个元素绘制一条线。数越少,线的间隔越短。alpha是用0-1的实数指定图形透明度的选项,值越接近1,越不透明。
如果z轴的刻度采用默认值,那么数值就会重叠在一起。因此,使用ax.set_zticks((0, 0, 2))把z的刻度限定为0和0.2(代码清单中的(E))。
(F)中的ax.view_init(变量1, 变量2)用于调节三维图形的方向,“变量1”表示纵向旋转角度,当它为0时,图形是从正侧面观察到的图形;当它为90时,则是从正上方观察到的图形。“变量2”表示横向旋转角度,当它为正数时,图形会按照顺时针方向旋转;当它为负数时,则会按照逆时针方向旋转。
本代码是以9×9的分辨率绘制的函数图形,把分辨率提高到50×50,即令rstride=5、cstride=5。分辨率越高,图形越清晰。这样可以更加直观地理解函数的形状。
3.7 contour绘制等高线
要想定量了解函数的高度,一个方便的方法是使用如下代码绘制等高线。
xn = 50
x0 = np.linspace(-2, 2, xn)
x1 = np.linspace(-2, 2, xn)
y = np.zeros((xn, xn))
for i0 in range(xn):
for i1 in range(xn):
y[i1, i0] = f3(x0[i0], x1[i1])
xx0, xx1 = np.meshgrid(x0, x1) # (A)
plt.figure(1, figsize=(4, 4))
cont = plt.contour(xx0, xx1, y, 5, colors='black') # (B)
cont.clabel(fmt='%.2f', fontsize=8) # (C)
plt.xlabel('$x_0$', fontsize=14)
plt.ylabel('$x_1$', fontsize=14)
plt.show()
输出结果:
代码清单前半部分以50×50的分辨率生成了xx0、xx1和y(到(A)为止的代码)。这是因为,如果不把分辨率提升到一定程度,就无法准确绘制等高线的图形。
(B)中的plt.contour(xx0, xx1, y, 5, colors=‘black’)用于绘制等高线。5用于指定显示的高度共有5个级别,而colors=‘black’,用于指定等高线的颜色为黑色。
把plt.contour的返回值保存在cont中,并运行。cont.clabel(fmt=‘%.2f’, fontsize=8),可以在各个等高线上显示高度值(©)。fmt=‘%.2f’用于指定数值格式,fontsize选项用于指定字符的大小。
以下内容为附加matplotlib学习资料,共两份。
matplotlib学习资料1
目录
1.figure学习
2.设置坐标轴
4.Legend 图例
4.Annotation 标注
5.tick能见度
1.figure学习
import matplotlib.pyplot as plt
import numpy as np
#导入包
x=np.linspace(-3,3,50)#产生-3到3之间50个点
y1=2*x+1#定义函数
y2=x**2
# 绘制直线
plt.figure()
plt.plot(x,y1)
运行结果:
曲线与直线绘制一块
# num=3表示图片上方标题 变为figure3,figsize=(长,宽)设置figure大小
plt.figure(num=3,figsize=(8,5))
plt.plot(x,y2)
# 红色虚线直线宽度默认1.0
plt.plot(x,y1,color='red',linewidth=1.0,linestyle='--')
plt.show()
运行结果:
2.设置坐标轴
# num=3表示图片上方标题 变为figure3,figsize=(长,宽)设置figure大小
plt.figure(num=3,figsize=(8,5))
plt.plot(x,y2)
# 红色虚线直线宽度默认1.0
plt.plot(x,y1,color='red',linewidth=1.0,linestyle='--')
plt.xlim((-1,2))#设置x轴范围
plt.ylim((-2,3))#设置轴y范围
#设置坐标轴含义, 注:英文直接写,中文需要后面加上fontproperties属性
plt.xlabel(u'价格',fontproperties='SimHei')
plt.ylabel(u'利润',fontproperties='SimHei')
# 设置x轴刻度
# -1到2区间,5个点,4个区间,平均分:[-1.,-0.25,0.5,1.25,2.]
new_ticks=np.linspace(-1,2,5)
print(new_ticks)
plt.xticks(new_ticks)
# 设置y轴刻度
'''
设置对应坐标用汉字或英文表示,后面的属性fontproperties表示中文可见,不乱码,
内部英文$$表示将英文括起来,r表示正则匹配,通过这个方式将其变为好看的字体
如果要显示特殊字符,比如阿尔法,则用转意符\alpha,前面的\ 表示空格转意
'''
plt.yticks([-2,-1.8,-1,1.22,4.],
['非常糟糕','糟糕',r'$good\ \alpha$',r'$really\ good$','超级好'],fontproperties='SimHei')
plt.show()
运行结果:
# num=3表示图片上方标题 变为figure3,figsize=(长,宽)设置figure大小
plt.figure(num=3,figsize=(8,5))
plt.plot(x,y2)
# 红色虚线直线宽度默认1.0
plt.plot(x,y1,color='red',linewidth=1.0,linestyle='--')
# 设置边框/坐标轴
gca='get current axis/获取当前轴线'
ax=plt.gca()
# spines就是脊梁,即四个边框
# 取消右边与上边轴
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
# matlibplot并没有设置默认的x轴与y轴方向,下面就开始设置默认轴
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
# 设置坐标原点
# 实现将(0,-1)设为坐标原点
# 设置y轴上-1为坐标原点的y点,把x轴放置再-1处
ax.spines['bottom'].set_position(('data',-1)) # 也可以是('axes',0.1)后面是百分比,相当于定位到10%处
# 设置x轴上0为坐标原点的x点,将y轴移置0处
ax.spines['left'].set_position(('data',0))
# 再写一遍以下代码,因为以上使用set_position后,中文会显示不出来
plt.yticks([-2,-1.8,-1,1.22,4.],
['非常糟糕','糟糕',r'$good\ \alpha$',r'$really\ good$','超级好'],fontproperties='SimHei')
plt.show()
运行结果:
4.Legend 图例
import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(-3,3,50)
y1=2*x+1
y2=x**2
# 绘制直线
plt.figure()
# plt.plot(x,y1)
# 曲线与直线绘制一块
# num=3表示图片上方标题 变为figure3,figsize=(长,宽)设置figure大小
plt.figure(num=3,figsize=(8,5))
# 设置x轴范围
plt.xlim((-1,2))
# 设置轴y范围
plt.ylim((-2,3))
# 设置坐标轴含义
# 注:英文直接写,中文需要后面加上fontproperties属性
plt.xlabel(u'价格',fontproperties='SimHei')
plt.ylabel(u'利润',fontproperties='SimHei')
# -1到2区间,5个点,4个区间,平均分:[-1.,-0.25,0.5,1.25,2.]
new_ticks=np.linspace(-1,2,5)
# print(new_ticks)
plt.xticks(new_ticks)
plt.yticks([-2,-1.8,-1,1.22,4.],
['非常糟糕','糟糕',r'$good\ \alpha$',r'$really\ good$','超级好'],fontproperties='SimHei')
# 设置legend图例
l1,=plt.plot(x,y2) # 可添加label属性,只不过如果这里添加了,下面legend再添加,下面的就会覆盖此处的!
# 红色虚线直线宽度默认1.0
l2,=plt.plot(x,y1,color='red',linewidth=1.0,linestyle='--')
'''
prop={'family':'SimHei','size':15}显示中文
legend(hadles=[,,],labels=[,,],loc='best/upper right/upper left/.../lower right')
handles就是你给他添加legend的线,如果要用handles,则前面的plt.plot,必须用l1,形式(不要忘记逗号)
此处labels会覆盖上述的plt.plot()的label
loc默认是best,给你放在一个合适的位置上,如果你拉伸弹框,位置会跟着变,自动放置合适位置
'''
plt.legend(handles=[l1,l2],prop={'family':'SimHei','size':15},loc='lower right',labels=['直线','曲线'])
plt.show()
运行结果:
4.Annotation 标注
import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(-3,3,20)
y=2*x+1
# 绘制直线
plt.figure(num=1,figsize=(8,5),)
plt.plot(x,y)
# gca='get current axis/获取当前轴线'
ax=plt.gca()
# spines就是脊梁,即四个边框
# 取消右边与上边轴
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',-0)) # 也可以是('axes',0.1)后面是百分比,相当于定位到10%处
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
# 绘制特定散点
x0=1
y0=2*x0+1
# plot散点图,上述plt.plot(x,y)变为plt.scatter(x,y)绘制出来就是散点图
# s代表大小,b代表blue
plt.scatter(x0,y0,s=50,color='b')
# 把两个点放进去plot一下,画出垂直于x轴的一条线,[x0,x0]表示两个点的x,[0,y0]表示两个点的y
# 绘制(x0,y0)垂直于x轴的线
# k--表示黑色虚线,k代表黑色,--表示虚线,lw表示线宽
plt.plot([x0,x0],[0,y0],'k--',lw=2.5)
# 添加注释 annotate
'''
其中参数xycoords='data' 是说基于数据的值来选位置, xytext=(+30, -30) 和 textcoords='offset points'
对于标注位置的描述 和 xy 偏差值, arrowprops是对图中箭头类型的一些设置.
'''
plt.annotate(r'$2x+1=%s$'%y0,xy=(x0,y0),xycoords='data',xytext=(+30,-30),textcoords='offset points',fontsize=16,arrowprops=dict(arrowstyle='->',connectionstyle='arc3,rad=.2'))
# 添加注释 text
# 其中-4.7, 3,是选取text的位置, 空格需要用到转字符\ ,fontdict设置文本字体.
plt.text(-4.7,3,r'$This\ is\ the\ some\ text.\mu\ \sigma_i\ \alpha_t$',
fontdict={'size':'16','color':'red'})
plt.show()
运行结果:
5.tick能见度
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-3, 3, 50)
y = 0.1*x
plt.figure()
# 设置 zorder 给 plot 在 z 轴方向排序
plt.plot(x, y, linewidth=10, zorder=1)
plt.ylim(-2, 2)
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data', 0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data', 0))
# 调整坐标
# 对被遮挡的图像调节相关透明度,本例中设置 x轴 和 y轴 的刻度数字进行透明度设置
for label in ax.get_xticklabels()+ax.get_yticklabels():
label.set_fontsize(12)
'''
其中label.set_fontsize(12)重新调节字体大小,bbox设置目的内容的透明度相关参,
facecolor调节 box 前景色,edgecolor 设置边框, 本处设置边框为无,alpha设置透明度.
'''
# 其中label.set_fontsize(12)重新调节字体大小,bbox设置目的内容的透明度相关参,
# facecolor调节 box 前景色,edgecolor 设置边框, 本处设置边框为无,alpha设置透明度.
label.set_bbox(dict(facecolor='white',edgecolor='none',alpha=0.7))
plt.show()
运行结果:
matplotlib学习资料2
本部分内容源自《利用python进行数据分析第二版》
目录
1. Figures and Subplots(图和子图)
2. Colors, Markers, and Line Styles(颜色,标记物,线样式)
3. Ticks, Labels, and Legends(标记,标签,图例)
4. Annotations and Drawing on a Subplot(注释和在subplot上画图)
5. Saving Plots to File(把图保存为文件)
6. matplotlib Configuration(matplotlib设置)
要用Jupyter notebook进行可交互式的绘图,需要执行下面的语句,这样就可以直接在Notebook里绘图了。
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
data = np.arange(10)#生成数据
data
#输出结果:array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
plt.plot(data)
输出结果:
seaborn和pandas内建的一些绘图函数能帮省去很多画图的繁杂工作,但如果想要定制化地做出一些函数无法绘出的图,就需要了解一些matplotlib的API了。
1. Figures and Subplots(图和子图)
在matplotlib中画的图,都是在Figure对象中的。可以用plt.figure创建一个:
fig = plt.figure()
输出结果:
如果实在ipython里执行,可以看到一个空白的绘图窗口出现,但是在jupyter中没有任何显示,除非输入一些命令。plt.figure有一些选择,其中figsize保证figure有固定的大小和长宽比,这样也方便保存到磁盘中。
不能在一个空白的figure上绘图,必须要创建一个或更多的subplots(子图),用add_subplot:
ax1 = fig.add_subplot(2, 2, 1)
这行代码的意思是,figure是2x2(这样一共有4幅图),而且选中4个subplots(数字从1到4)中的第1个。如果要创建另外两个子图,可以输入:
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)
fig
输出结果:
有一个注意点,在使用Jupyter notebook的时候,绘图可能在一个cell之后被重置,所以对于一些复杂的绘图,必须把绘图命令全部放在一个notebook cell中。
这里在一个cell中执行这些命令:
fig = plt.figure()
ax1 = fig.add_subplot(2, 2, 1)
ax2 = fig.add_subplot(2, 2, 2)
ax3 = fig.add_subplot(2, 2, 3)
# 下面出现交互式界面后,不要关闭,运行之后的命令,可以看到最后一副图中出现了线
输出结果:
如果输入plt.plot([1.5, 4.5, -2, 1.6])
这样的命令,matplotlib会把图画在最后一个figure的最后一个子图上。
plt.plot(np.random.randn(50).cumsum(), 'k--')
'k–'是一个style(样式)选项,它表示使用黑色的虚线。在这里,fig_add_subplot返回的是一个AxesSubplot对象,可以直接在空白的subplot上绘图,直接在对应的AxesSubplot对象上调用方法即可:
_ = ax1.hist(np.random.randn(100), bins=20, color='k', alpha=0.3)
ax2.scatter(np.arange(30), np.arange(30) + 3 * np.random.randn(30))
fig
输出结果:
因为创建一个带有多个subplot的figure是很常见的操作,所以matplotlib添加了一个方法,plt.subplots,来简化这个过程。这个方法会创建一个新的figure,并返回一个numpy数组,其中包含创建的subplot对象:
f, axes = plt.subplots(2, 3)
输出结果:
axes
这个操作是很有用的。axes能用一个二位数据来索引,例如,axes[0, 1]。可以使用sharex和sharey来指定不同subplot有相同的x-或y-axis(其实就是令坐标轴的范围相同),这能让在同一范围内进行数据之间的比较。不然的话,matplotlib会自动绘图的范围不一定是一样的。
Adjusting the spacing around subplots(调整subplot直接的间隔)
默认情况下,matplotlib会在subplot之间留下一定间隔的边距,这取决于绘图的高度和跨度。所以如果调整绘图的大小,它会自动调整。可以用Figure对象下的subplots_adjust方法来更改间隔,当然,也可以用第一层级的函数:
subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=None)
wspace和hspace控制figure宽度和长度的百分比,可以用来控制subplot之间的间隔。这里有一个例子,让间隔为0:
fig, axes = plt.subplots(2, 2, sharex=True, sharey=True)
for i in range(2):
for j in range(2):
axes[i, j].hist(np.random.randn(500), bins=50, color='k', alpha=0.5)
plt.subplots_adjust(wspace=0, hspace=0)
输出结果:
注意到轴上有些标签重叠了。matplotlib不会检查标签是否重叠,所以需要直接规定明确的tick location(记号位置)和tick labels(记号标签),这部分会在之后介绍。
2. Colors, Markers, and Line Styles(颜色,标记物,线样式)
matplotlib的plot主函数能接受x和y坐标,在可选项中,字符串能指定颜色和线样式。例如,画出x和y,用绿色的点线:
ax.plot(x, y, 'g--')
这种方法可以很方便的同时指定颜色和线样式;不过有些用户可能不喜欢直接把规定颜色和样式的字符串写在一起,当然,也可以写得更明确一些:
ax.plot(x, y, linestyle='--', color='g')
有很多可供选择的颜色缩写,当然,也可以使用任意的颜色,通过制定hex code(十六进制码,比如’#CECECE’)。通过查看plot的字符串文档,可以看到可供选择的所有线样式(直接输入plot?
)。
另外还可以用markers(标记物)来高亮实际的数据点。因为matplotlib创建一个continuous line plot(连续线条图)的话,如果想要插入,可能看不清楚哪里可以插入数据点。而marker可以作为样式的一部分,字符串必须按颜色,标记物类型,样式这样的顺序:
plt.plot(np.random.randn(30).cumsum(), 'ko--')
当然,也快成写得更准确一些:
plt.plot(np.random.randn(30).cumsum(), color='k', linestyle='dashed', marker='o')
对于点线图,注意到,默认情况下,后续点是通过线性添加上的。这个可以通过drawstyle来更改:
data = np.random.randn(30).cumsum()
plt.plot(data, 'k--', label='Default')
plt.plot(data, 'k-', drawstyle='steps-post', label='steps-post')
plt.legend(loc='best')
当运行上面命令时,注意到,输出有<matplotlib.legend.Legend at 0x10906fda0>
这样的字样。这是matplotlib返回添加的那些子图的索引。大部分时候可以无视这种输出。这里,把label传递给了plot,这样通过plt.legend显示出每条线的意义。
注意:必须调用plt.legend(或ax.legend,如果有axes的话)来创建一个legend(图例),不论是非传入label。(译者:经测试,如果不调用plt.legend的话,是看不到label的)
3. Ticks, Labels, and Legends(标记,标签,图例)
对于大部分绘图的装饰,有两种主要的方法:使用pyplot(matplotlib.pyplot)和用更对象导向的简单的matplotlib API。
pyplot界面是为交互式使用而设计的,它包含很多方法,比如xlim, xticks, xticklabels。这些方法控制绘图的范围,标记位置,标记标签。有两种使用方法:
- 调用的时候不传入参数,使用当前的参数设置(例如,plt.xlim()返回当前X轴的范围)
- 调用的时候传入参数,使用传入的参数设置(例如,plt.xlim([0, 10]), 令X轴的范围从0到10)
所有这些方法,作用于激活的或最新创建的AxesSubplot对象上。每一个都在subplot有对应的两个方法;比如对于xlim,就有对应的ax.get_xlim和ax.set_xlim。这里作者使用subplot的方法,这样会更清晰。
Setting the title, axis labels, ticks, and ticklabels(设定标题,轴标签,标记,标记标签)
这里创建一个简单的图,画一个随机漫步:
fig = plt.figure() # 直到下一个黑体标题出现前,不要关闭这个fig
输出结果:
ax = fig.add_subplot(1, 1, 1)
ax.plot(np.random.randn(1000).cumsum())
为了改变x-axis tick(x轴标记),使用set_xticks和set_xticklabels。前者告诉matplotlib沿着x轴的范围,把标记放在哪里;默认会把所在位置作为标签,但可以用set_xticklabels来设置任意值作为标签:
ticks = ax.set_xticks([0, 250, 500, 750, 1000])
labels = ax.set_xticklabels(['one', 'two', 'three', 'four', 'five'],
rotation=30, fontsize='small')
rotation选项让x轴上的标记标签有一个30度的旋转。set_xlabel给x轴一个名字,而set_title给subplot一个标题:
ax.set_title('My first matplotlib plot')
#输出:Text(0.5, 1.0, 'My first matplotlib plot')
ax.set_xlabel('Stages')
#输出:Text(0.5, 0, 'Stages')
用相同的流程来更改y轴,把上面代码里的x变为y。axes类有一个set方法,能让一次设置很多绘图特性。对于上面的例子,可以写成下面这样:
props = {
'title': 'My first matplotlib plot',
'xlabel': 'Stage'
}
ax.set(**props)
#输出:[Text(0.5, 1.0, 'My first matplotlib plot'), Text(0.5, 0, 'Stage')]
Adding legends (添加图例)
图例对于绘图很重要。有很多方式可以添加图例。最简单的方法是用label参数:
from numpy.random import randn
fig = plt.figure(); ax = fig.add_subplot(1, 1, 1)
输出结果:
ax.plot(randn(1000).cumsum(), 'k', label='one')
ax.plot(randn(1000).cumsum(), 'k--', label='two')
ax.plot(randn(1000).cumsum(), 'k.', label='three')
做完了上面的部分,调用ax.legend()或plt.legend(),来自动创建图例:
ax.legend(loc='best')
legend方法有一些选项,比如用loc参数设定位置。更多信息,可以参考字符串文档(ax.legend?)
loc告诉matplotlib把图例放在哪里。如果不挑剔的话,直接设定’best’就可以了,它会自动选择一个合适的位置。如果想要从图例中排除一个或更多的元素,那就不要传入label,或设置label='_nolegen_'
。
4. Annotations and Drawing on a Subplot(注释和在subplot上画图)
除了标准的绘图类型,可能希望画出自己的绘图注释,包括文本,箭头或其他形状。可以添加注释和文本,通过text,arrow,和annotate函数。text能在指定的坐标(x, y)上写出文本,还可以自己设定样式:
ax.test(x, y, 'Hello world!', family='monospace', fontsize=10)
注释可以画出文本和箭头。这里做一个例子,画出S&P 500指数自2007年后的价格,并用注释指出在2008~2009年经融危机期间一些重要的日期。
下面的内容可以在一个cell里直接执行:
from datetime import datetime
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
data = pd.read_csv('examples/spx.csv', index_col=0, parse_dates=True)
spx = data['SPX']
spx.plot(ax=ax, style='k-')
crisis_data = [
(datetime(2007, 10, 11), 'Peak of bull market'),
(datetime(2008, 3, 12), 'Bear Stearns Fails'),
(datetime(2008, 9, 15), 'Lehman Bankruptcy')
]
for date, label in crisis_data:
ax.annotate(label, xy=(date, spx.asof(date) + 75),
xytext=(date, spx.asof(date) + 225),
arrowprops=dict(facecolor='black', headwidth=4,
width=2, headlength=4),
horizontalalignment='left', verticalalignment='top')
# Zoom in on 2007-2010
ax.set_xlim(['1/1/2007', '1/1/2011'])
ax.set_ylim([600, 1800])
ax.set_title('Important dates in the 2008-2009 financial crisis')
在这幅图里,有一些点是值得强调的:ax.annotate方法能在x和y坐标指示的位置画出标签。可以用set_xlim和set_ylim方法来手动地设置开始和结束的边界,而不是用matplotlib的默认边界。最后,ax.set_title添加一个主标题。
可以联网看matplotlib gallery上查看更多关于标注的例子。
要想画出图形的话,更需要细心一些。matplotlib有一些对象可以用来表示一些常见的图形,被称之为patches。其中一些,比如Rectangle和Circle,在matplotlib.pyplot也有,但是全套画图形的方法还是在matplotlib.patches里。
给图中添加一个图形,必须先添加一个patch对象,shp,然后通过调用ax.add_patch(shp)把它添加到subplot中:
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
rect = plt.Rectangle((0.2, 0.75), 0.4, 0.15, color='k', alpha=0.3)
circ = plt.Circle((0.7, 0.2), 0.15, color='b', alpha=0.3)
pgon = plt.Polygon([[0.15, 0.15], [0.35, 0.4], [0.2, 0.6]],
color='g', alpha=0.5)
ax.add_patch(rect)
ax.add_patch(circ)
ax.add_patch(pgon)
输出结果:
5. Saving Plots to File(把图保存为文件)
可以用plt.savefig来保存图。这个方法等同于直接在figure对象上调用savefig方法。例如,想要保存一个SVG版本的图片,键入:
`plt.savefig('figpath.svg)`
保存的文件类型通过文件名后缀来指定。即如果使用 .pdf做为后缀,就会得到一个PDF文件。这里有一些重要的设置,作者经常用来刊印图片:
- dpi,控制每英寸长度上的分辨率
- bbox_inches, 能删除figure周围的空白部分
比如想要得到一幅PNG图,有最小的空白,400 DPI,键入:
plt.savefig('figpath.png', dpi=400, bbox_inches='tight')
savefig不仅可以写入磁盘,还可以导出为任意像是文件一样的对象,比如BytesIO:
from io import BytesIO
buffer = BytesIO()
plt.savefig(buffer)
plot_data = buffer.getvalue()
6. matplotlib Configuration(matplotlib设置)
matplotlib很多默认的设置是可以自己定义的,通过修改一些全局设定,比如图大小,subplot间隔,颜色,字体大小,网格样式等等。一种更累设定的方式是用rc方法,例如,想要设置全局的图大小为10 x 10,键入:
plt.rc('figure', figsize=(10, 10))
rc中的第一个参数是想要自定义的组件,比如’figure’, ‘axes’, ‘xtick’, ‘ytick’, ‘grid’, ‘legend’,或其他。然后添加一个关键字来设定新的参数。一个比较方便的写法是把所有的设定写成一个dict:
font_options = {'family': 'monospace',
'weight': 'bold',
'size' : 'small'}
plt.rc('font', **font_options)
更详细的设定可以去看一下文档,matplotlib影城而设置文件matplotlibrc,位于matplotlib/mlp-data文件夹下。如果按自己的方式修改这个文件,并把这个文件放在主目录下,更名为*.matplotlibrc*的话,在每次启动matplotlib的时候,会自动加载这个文件。