import matplotlib.pyplot as plt #调用matplotlib中的子模块pyplot绘制折线图
# 定义2个列表分别作为X轴、Y轴数据
x_data = ['2012','2013', '2014', '2015', '2016', '2017', '2018', '2019']
y_data = [45000,58000, 60200, 63000, 71000, 84000, 90500, 107000]
# 第一个列表代表横坐标的值,第二个代表纵坐标的值
plt.plot(x_data, y_data)
# 调用show()函数显示图形
plt.show()
其实可以看到python中的绘图和matlab中的绘图一模一样,当然,也可以类似的修改线型、色彩、线宽等属性。
import matplotlib.pyplot as plt
#定义两组数据的x,y坐标
x_axis=['2010','2011','2012','2013','2014','2015','2016','2017','2018','2019']
y1_axis=[12900,13500,14700,15223,25790,26489,27678,28900,29213,31290]
y2_axis=[16900,17500,18700,25223,27790,29489,30678,33900,34213,35290]
# 指定两条折线的颜色、线宽和样式
plt.plot(x_axis, y1_axis, color = 'green', linewidth = 2.0, linestyle = '--')
plt.plot(x_axis, y2_axis, color = 'blue', linewidth = 3.0, linestyle = '-.')
#调用show()函数显示图形
plt.show()
import matplotlib.pyplot as plt
#定义x坐标值
x_data = ['2011', '2012', '2013', '2014', '2015', '2016', '2017','2018','2019']
# 定义2个列表分别作为两条折线的Y轴数据
y_data = [57000, 61200, 62000, 699000, 83500, 91500, 107000,11900,12800]
y_data2 = [51000, 53200, 56500,59300, 60800, 65500, 69700,73000,82050]
# 指定折线的颜色、线宽和样式,ln1和ln2是plot函数的返回值,相当于matlab中的句柄
ln1,= plt.plot(x_data, y_data, color = 'red', linewidth = 2.0, linestyle = '--')
ln2,= plt.plot(x_data, y_data2, color = 'blue', linewidth = 3.0, linestyle = '-.')
# 调用legend函数设置图例
plt.legend(handles=[ln1, ln2], labels=['June Sale Amount', 'July Sale Amount'],loc='best')
# 调用show()函数显示图形
plt.show()
运行结果如下:
上述例2中需要注意的是有以下几点:
1、plot的返回值有多个,其中第一个返回值代表该图形,因此使用ln1,(一定要有逗号)返回第一个返回值;
2.legend函数的第一个参数即是函数plot的第一个返回值(如果第一个参数没有指明,则按照顺序为折线图中的多条折线添加图例);第二个参数为图例的内容,第三个参数是图例所放置的位置,一般具有如下表中的位置参数:
位置参数及意义 |
'best':自动选择最佳位置 |
'upper right':将图例放在右上角。 |
'upper left':将图例放在左上角 |
'lower left':将图例放在左下角 |
'lower right':将图例放在右下角 |
'right':将图例放在右边 |
'center left':将图例放在左边居中的位置 |
'center right':将图例放在右边居中的位置 |
'lower center':将图例放在底部居中的位置 |
'upper center':将图例放在顶部居中的位置 |
'center':将图例放在中心 |
3.Matplotlib 也允许在调用 plot() 函数时为每条折线分别传入 label 参数,这样程序在调用 legend() 函数时就无须传入 labels、handles 参数了:
import matplotlib.pyplot as plt
#定义两组数据的x,y坐标
x_axis=['2010','2011','2012','2013','2014','2015','2016','2017','2018','2019']
y1_axis=[12900,13500,14700,15223,25790,26489,27678,28900,29213,31290]
y2_axis=[16900,17500,18700,25223,27790,29489,30678,33900,34213,35290]
# 指定两条折线的颜色、线宽和样式
#ln1,和ln2均为函数句柄,函数句柄是函数的返回值,可用来调用函数对图形进行操作
plt.plot(x_axis, y1_axis, color = 'green', linewidth = 2.0, linestyle = '--',label='C++')
plt.plot(x_axis, y2_axis, color = 'blue', linewidth = 3.0, linestyle = '-.',label='Python')
#调用show()函数显示图形
plt.show()
4.如果图例内容是中文字体,那么上述代码将不会显示图例,需要添加下述代码块:
import matplotlib.font_manager as fm
# 使用Matplotlib的字体管理器加载中文字体
my_font=fm.FontProperties(fname="C:\Windows\Fonts\simkai.ttf")
# 调用legend函数设置图例
plt.legend(handles=[ln2, ln1], labels=['六月销售额', '七月销售额'],
loc='lower right', prop=my_font)
5.Python默认的图例字体是英文字体,那么我们也可以通过以下方式改变python图例的默认字体:
在 python交互式解释器中输入如下两行命令:
import matplotlib
matplotlib.matplotlib_fname()
'D:\\Python\\Python36\\lib\\site-packages\\matplotlib\\mp1-data\\matplotlibrc'
其中 matplotlib_fname() 函数会显示 Matplotlib 配置文件的保存位置,此处显示该文件的存储路径为 D:\Python\Python36\lib\site-packages\matplotlib\mpl-data\matplotlibrc。打开该文件,找到如下这行代码:
#font.family:sans-serif
上面这行代码用于配置 Matplotlib 的默认字体,取消运行配置代码之前的注释符号(#),并将后面的 sans-serif 修改为本地己有的中文字体。例如使用微软雅黑字体,只要将上面的配置代码修改为如下形式即可:
font.family: Microsoft YaHei
通过上面设置,即可改变 Matplotlib 的默认字体,这样即可避免每次调用 legend() 函数时都需要额外指定字体。
python可以调用 xlable() 和 ylabel() 函数分别设置 X 轴、Y 轴的名称,也可以通过 title() 函数设置整个数据图的标题,还可以调用 xticks()、yticks() 函数分别改变 X 轴、Y 轴的刻度值(允许使用文本作为刻度值)。如下例:
例3:
import matplotlib.pyplot as plt
x_data = ['2011', '2012', '2013', '2014', '2015', '2016', '2017','2018','2019']
# 定义2个列表分别作为两条折线的Y轴数据
y_data = [56000, 62200, 64000, 73000, 85600, 92500, 120000,135000,146000]
y_data2 = [51000, 53200, 54500,56300, 57500, 59800, 64700,68900,72900]
import matplotlib.font_manager as fm
# 使用Matplotlib的字体管理器加载中文字体
my_font=fm.FontProperties(fname="C:\Windows\Fonts\simkai.ttf")
# 指定折线的颜色、线宽和样式
plt.plot(x_data, y_data, color = 'red', linewidth = 2.0,
linestyle = '--', label='Juna')
plt.plot(x_data, y_data2, color = 'blue', linewidth = 3.0,
linestyle = '-.', label='July')
# 调用legend函数设置图例
plt.legend(loc='best')
# 设置数据图的标题
plt.title('Sale Amount in Juna or July')
# 设置两条坐标轴的标签
plt.xlabel("Year")
plt.ylabel("Sale")
# 设置Y轴上的刻度值:第一个参数是点的位置,第二个参数是点的文字提示
plt.yticks([60000, 85000, 120000],[r'Good', r'Wonderful', r'Hot'])
# 调用show()函数显示图形
plt.show()
运行结果为:
如果需要进一步设置图形,可以添加以下代码:
ax = plt.gca()
# 设置将X轴的刻度值放在底部X轴上
ax.xaxis.set_ticks_position('bottom')
# 设置将Y轴的刻度值放在底部X轴上
ax.yaxis.set_ticks_position('left')
# 设置右边坐标轴线的颜色(设置为none表示不显示)
ax.spines['right'].set_color('none')
# 设置顶部坐标轴线的颜色(设置为none表示不显示)
ax.spines['top'].set_color('none')
# 定义底部坐标轴线的位置(放在85000数值处)
ax.spines['bottom'].set_position(('data', 70000))
运行结果为:
和matlab一样,python调用 subplot() 函数可以创建一个子图,然后程序就可以在子图上进行绘制。
subplot(nrows, ncols, index, **kwargs) 函数的 nrows 参数指定将数据图区域分成多少行;ncols 参数指定将数据图区域分成多少列;index 参数指定获取第几个区域。
subplot() 函数也支持直接传入一个三位数的参数,其中第一位数将作为 nrows 参数;第二位数将作为 ncols 参数;第三位数将作为 index 参数。
例4:
import matplotlib.pyplot as plt
import numpy as np
plt.figure()
# 定义从-2*pi到2*pi之间的数据,平均取128个数据点
x_data = np.linspace(-2*np.pi, 2*np.pi, 128, endpoint=True) # ①
# 将整个figure分成两行两列,第三个参数表示该图形放在第1个网格
plt.subplot(2, 2, 1)
# 绘制正弦曲线
plt.plot(x_data, np.sin(x_data))
plt.gca().spines['right'].set_color('none')
plt.gca().spines['top'].set_color('none')
plt.gca().spines['bottom'].set_position(('data', 0))
plt.gca().spines['left'].set_position(('data', 0))
plt.title('Curve of Sin()')
# 将整个figure分成两行两列,并将该图形放在第2个网格
plt.subplot(2,2,2)
# 绘制余弦曲线
plt.plot(x_data, np.cos(x_data))
plt.gca().spines['right'].set_color('none')
plt.gca().spines['top'].set_color('none')
plt.gca().spines['bottom'].set_position(('data', 0))
plt.gca().spines['left'].set_position(('data', 0))
plt.title('Curve of Cos()')
# 将整个figure分成两行两列,并该图形放在第3个网格
plt.subplot(2,2,3)
# 绘制正切曲线
plt.plot(x_data, np.tan(x_data))
plt.gca().spines['right'].set_color('none')
plt.gca().spines['top'].set_color('none')
plt.gca().spines['bottom'].set_position(('data', 0))
plt.gca().spines['left'].set_position(('data', 0))
plt.title('Curve of Tan()')
plt.show()
例:
#注明:此程序来源于Python教程
import matplotlib.pyplot as plt
# 准备数据
data = [0.16881, 0.14966, 0.07471, 0.06992,
0.04762, 0.03541, 0.02925, 0.02411, 0.02316, 0.01409, 0.36326]
# 准备标签
labels = ['Java', 'C', 'C++', 'Python',
'Visual Basic .NET', 'C#', 'PHP', 'JavaScript',
'SQL', 'Assembly langugage', '其他']
# 将第4个语言(Python)分离出来:突出Pyhon的效果
explode = [0, 0, 0, 0.3, 0, 0, 0, 0, 0, 0, 0]
# 使用自定义颜色
colors=['red', 'pink', 'magenta','purple','orange']
# 将横、纵坐标轴标准化处理,保证饼图是一个正圆,否则为椭圆
plt.axes(aspect='equal')
# 控制X轴和Y轴的范围(用于控制饼图的圆心,半径)
plt.xlim(0,8)
plt.ylim(0,8)
# 绘制饼图
plt.pie(x = data, # 绘图数据
labels=labels, # 添加编程语言标签
explode=explode, # 突出显示Python
colors=colors, # 设置饼图的自定义填充色
autopct='%.3f%%', # 设置百分比的格式,此处保留3位小数
pctdistance=0.8, # 设置百分比标签与圆心的距离
labeldistance = 1.15, # 设置标签与圆心的距离
startangle = 180, # 设置饼图的初始角度
center = (4, 4), # 设置饼图的圆心(相当于X轴和Y轴的范围)
radius = 3.8, # 设置饼图的半径(相当于X轴和Y轴的范围)
counterclock = False, # 是否逆时针,这里设置为顺时针方向
wedgeprops = {'linewidth': 1, 'edgecolor':'green'},# 设置饼图内外边界的属性值
textprops = {'fontsize':12, 'color':'black'}, # 设置文本标签的属性值
frame = 1) # 是否显示饼图的圆圈,此处设为显示
# 不显示X轴和Y轴的刻度值
plt.xticks(())
plt.yticks(())
# 添加图标题
plt.title('Ranking of All language')
# 显示图形
plt.show()
运行结果为:
例6:
#Python绘制垂直柱状图:
import matplotlib.pyplot as plt
import numpy as np
# 构建数据
x_data = ['2012', '2013', '2014', '2015', '2016', '2017', '2018','2019']
y_data1 = [58000, 60200, 62500, 72000, 83000, 90500, 106000,11500]
y_data2 = [53000, 54500, 51500,58300, 57900, 59500, 62700,70900]
# 绘图
plt.bar(x=x_data, height=y_data1, label='Book1', color='steelblue', alpha=0.7)
plt.bar(x=x_data, height=y_data2, label='Book2', color='indianred', alpha=0.7)
# 在柱状图上显示具体数值, ha参数控制水平对齐方式, va控制垂直对齐方式
for x, y in enumerate(y_data1):
plt.text(x, y + 100, '%s' % y, ha='center', va='bottom')
for x, y in enumerate(y_data2):
plt.text(x, y + 100, '%s' % y, ha='center', va='top')
# 设置标题
plt.title("Book1 and Book2")
# 为两条坐标轴设置名称
plt.xlabel("year")
plt.ylabel("sales")
# 显示图例
plt.legend()
plt.show()
运行结果如下:
为了能在柱状图上显示具体的数值,程序可以调用 text() 函数在数据图上输出文字。
text() 函数的前两个参数控制输出文字的 X、Y 坐标,第三个参数则控制输出的内容。其中 va 参数控制文字的垂直对齐方式,ha 参数控制文字的水平对齐方式。如上面程序所示,由于 X 轴数据是一个字符串列表,因此 X 轴实际上是以列表元素的索引作为刻度值的。因此,当程序指定输出文字的 X 坐标为0 时,表明将该文字输出到第一个条柱处;对于 Y 坐标而言,条柱的数值正好在条柱高度所在处(即2011年没有,从2012年开始呈现数据坐标图),如果指定 Y 坐标为条柱的数值 +100,就是控制将文字输出到条柱略上一点的位置。
为了将多个柱状图的条柱并列显示,程序需要为这些柱状图重新计算不同的 X 轴数据。为了精确控制条柱的宽度,程序可以在调用 bar() 函数时传入 width 参数,这样可以更好地计算条柱的并列方式。将上面程序改为如下形式:
例7:
#Python绘制垂直并列,且有空隙的柱状图:
import matplotlib.pyplot as plt
import numpy as np
# 构建数据
x_data = ['2012', '2013', '2014', '2015', '2016', '2017', '2018','2019']
y_data1 = [58000, 60200, 62500, 72000, 83000, 90500, 106000,115000]
y_data2 = [53000, 54500, 51500,58300, 57900, 59500, 62700,70900]
bar_width=0.35 #柱状的宽度
gap_width=0.05 #柱状与柱状之间的间隙宽度
# 将y_data1中的X轴数据改为使用range(len(x_data), 即0、1、2...
plt.bar(x=range(len(x_data)), height=y_data1, label='Book1',
color='steelblue', alpha=0.7, width=bar_width)
# 将y_data2中的X轴数据改为使用np.arange(len(x_data))+bar_width,
# 即bar_width、1+bar_width、2+bar_width...这样就和第一个柱状图实现了并列
plt.bar(x=np.arange(len(x_data))+bar_width+gap_width, height=y_data2,
label='Book2', color='indianred', alpha=0.7, width=bar_width)
# 在柱状图上显示具体数值, ha参数控制水平对齐方式, va控制垂直对齐方式
for x, y in enumerate(y_data1):
plt.text(x, y + 100, '%s' % y, ha='center', va='bottom')
for x, y in enumerate(y_data2):
plt.text(x+bar_width, y + 100, '%s' % y, ha='center', va='top')
# 设置标题
plt.title("Book1 and Book2")
# 为两条坐标轴设置名称
plt.xlabel("year")
plt.ylabel("sales")
plt.xticks(np.arange(len(x_data))+bar_width/2, x_data)
# 显示图例
plt.legend()
plt.show()
运算结果为:
例8:
#Python绘制水平柱状图:
import matplotlib.pyplot as plt
import numpy as np
# 构建数据
x_data = ['2012', '2013', '2014', '2015', '2016', '2017', '2018','2019']
y_data1 = [58000, 60200, 62500, 72000, 83000, 90500, 106000,115000]
y_data2 = [53000, 54500, 51500,58300, 57900, 59500, 62700,70900]
bar_width=0.35 #柱状的宽度
plt.barh(y=range(len(x_data)), width=y_data1, label='Book1',
color='steelblue', alpha=0.7, height=bar_width)
# Y轴数据使用np.arange(len(x_data))+bar_width,
# 就是bar_width、1+bar_width、2+bar_width...这样就和第一个柱状图并列了
plt.barh(y=np.arange(len(x_data))+bar_width, width=y_data2,
label='Book2', color='indianred', alpha=0.7, height=bar_width)
# 在柱状图上显示具体数值, ha参数控制水平对齐方式, va控制垂直对齐方式
for y, x in enumerate(y_data1):
plt.text(x+5000, y-bar_width/2, '%s' % x, ha='center', va='bottom')
for y, x in enumerate(y_data2):
plt.text(x+5000, y+bar_width/2, '%s' % x, ha='center', va='bottom')
# 为Y轴设置刻度值
plt.yticks(np.arange(len(x_data))+bar_width/2, x_data)
# 设置标题
plt.title("Book1 and Book2")
# 为两条坐标轴设置名称
plt.xlabel("Sales")
plt.ylabel("Year")
# 显示图例
plt.legend()
plt.show()
运行结果如下:
调用 Matplotlib 的 scatter() 函数来绘制散点图,该函数支持如下常用参数:
例9:
#绘制散点图
import matplotlib.pyplot as plt
import numpy as np
plt.figure()
# 定义从-2*pi到2*pi之间的数据,平均取128个数据点
x_data = np.linspace(-2*np.pi, 2*np.pi, 128, endpoint=True)
# 沿着正弦曲线绘制散点图
plt.scatter(x_data, np.sin(x_data), c='purple', # 设置点的颜色
s=50, # 设置点半径
alpha = 0.5, # 设置透明度
marker='p', # 设置使用五边形标记
linewidths=1, # 设置边框的线宽
edgecolors=['red', 'yellow']) # 设置边框的颜色
# 绘制第二个散点图(只包含一个起点),突出起点
plt.scatter(x_data[0], np.sin(x_data)[0], c='red', # 设置点的颜色
s=150, # 设置点半径
alpha =1) # 设置透明度
# 绘制第三个散点图(只包含一个结束点),突出结束点
plt.scatter(x_data[127], np.sin(x_data)[127], c='black', # 设置点的颜色
s=150, # 设置点半径
alpha =1) # 设置透明度
plt.gca().spines['right'].set_color('none')
plt.gca().spines['top'].set_color('none')
plt.gca().spines['bottom'].set_position(('data', 0))
plt.gca().spines['left'].set_position(('data', 0))
plt.title('Scatter Diagram of Sin()')
plt.show()
运行结果如下:
可以看到,例子中绘制了三条散点图,其中第一条是绘制的散点图(多个点),后面的是绘制了单点(即数据始发点和终止点)的散点图,并对其进行了一定的突出效果。
绘制等高线图需要三维数据,其中 X、Y 轴数据决定坐标点,还需要对应的高度数据(相当于 Z 轴数据)来决定不同坐标点的高度。Python可以调用 contour() 函数绘制等高线,调用 contourf() 函数为等高线图填充颜色。
在调用 contour()、contourf() 函数时可以指定如下常用参数:
#绘制等高线
import matplotlib.pyplot as plt
import numpy as np
#步骤一:首先,收集数据
delta = 0.025
# 生成代表X轴数据的列表
x = np.arange(-4.0, 4.0, delta)
# 生成代表Y轴数据的列表
y = np.arange(-3.0, 3.0, delta)
# 对x、y数据执行网格化
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
# 计算Z轴数据(高度数据)
Z = (Z1 - Z2) * 3
#步骤二:其次,等高线填充颜色
# 为等高线图填充颜色, 16指定将等高线分为几部分
plt.contourf(x, y, Z, 16, alpha = 0.8,
cmap='rainbow') # 使用颜色映射来区分不同高度的区域
#步骤三:最后,绘制等高线并设置坐标等
# 绘制等高线
C = plt.contour(x, y, Z, 16,
colors = 'black', # 指定等高线的颜色
linewidth = 0.5) # 指定等高线的线宽
# 绘制等高线数据
plt.clabel(C, inline = True, fontsize = 10)
# 去除坐标轴
plt.xticks(())
plt.yticks(())
# 设置标题
plt.title("Isoheight")
# 为两条坐标轴设置名称
plt.xlabel("Latitude")
plt.ylabel("Longitude")
plt.show()
运算结果为:
在Python中绘制 3D 图形,需要调用 Axes3D 对象的 plot_surface() 方法
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure(figsize=(12, 8))
ax = Axes3D(fig)
delta = 0.135
# 生成代表X轴数据的列表
x = np.arange(-3.0, 3.0, delta)
# 生成代表Y轴数据的列表
y = np.arange(-2.0, 2.0, delta)
# 对x、y数据执行网格化
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-X**2 - Y**2)
Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2)
# 计算Z轴数据(高度数据)
Z = (Z1 - Z2) * 2
# 绘制3D图形
ax.plot_surface(X, Y, Z,
rstride=1, # rstride(row)指定行的跨度
cstride=1, # cstride(column)指定列的跨度
cmap=plt.get_cmap('rainbow')) # 设置颜色映射
# 设置Z轴范围
ax.set_zlim(-2.5, 2.5)
# 设置标题
plt.title("Figure-3D")
plt.show()