「Python」matplotlib
matplotlib绘图总结
Matplotlib
引言
matplotlib中pyplot子模块提供了和matlab类似的绘图api,方便用户快速绘制一些可视化图标
引入
# way1: 调用函数是加plt前缀
import matplotlib.pyplot as plt
# way2: 引入pyplot的所有函数
from matplotlib.pyplot import *
# 引入pylab 设置字体显示中文
from pylab import rcParams
rcParams['font.sans-serif'] = ['SimHei'] # 设置字体
plt.rcParams["font.sans-serif"] = "SimHei"
plt.rcParams["axes.unicode_minus"] = False
常用函数
matplotlib官方文档
# 用 plot函数绘制折线图
# 用 subplot函数绘制多幅图表
# 用 imshow函数展示图片
# 用 hist函数绘制直方图
# 用 pie绘制饼图
# 用 legend绘制图例
plot函数
dataframe.plot(kind='xxx',title='xx') # kind='bar','line','hist','scatter'[散点图]
#单条线:
plot([x], y, [fmt], data=None, **kwargs)
#多条线一起画
plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
'''
参数解释:
x,y表示具体坐标点,可以是序列数据或者是标量
[fmt]--可选参数,是一个字符串用于定义图的基本属性。
such as:
color(颜色),marker(点型),linestyle(线型)
具体形式为:'[color][marker][line]' fmt接收的是每个属性的单个字母缩写
plot(x, y) # 默认配置
plot(x, y, '.') # 绘制点状标记
plot(x, y, 'bo-') # 绘制蓝色圆点实线
plot(x, y, 'g--') # 绘制绿色虚线
绘制sin函数
# 请绘制sin函数曲线
import matplotlib
import matplotlib.pyplot as plt
x = [0, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330, 360]
y= [0, 0.5, 0.866, 1, 0.866, 0.5, 0, -0.5, -0.866, -1, -0.866, -0.5, 0]
plt.plot(x,y,'.')
plt.show()

savefig保存
# 请绘制抛物线曲线
import matplotlib.pyplot as plt
def f(x):
return 3 * x * x + 2 * x + 1
x = range(0, 51, 1)
y = [f(e) for e in x]
plt.plot(x, y, 'r--')
plt.show()

legend()图例
legend() #以默认形式设置图例
legend(labels) #标记已有的绘图
legend(handles, labels) #明确定义图例中的元素
plt.legend(['A simple line'])
# 明确定义图例中的元素,即两条线分别绘制图例
line1, = plt.plot([1,2,3], linestyle='--')
line2, = plt.plot([3,2,1], linewidth=4)
plt.legend([line1,line2],["Line 1","Line 2"])
设置坐标轴/标题/画布大小
- plt.xlim、plt.ylim用于设置横纵坐标轴范围;
- plt.xlabel、plt.ylabel用于设置坐标轴名称;
- plt.xticks、plt.yticks用于设置坐标轴刻度;
- plt.title用于设置图像标题。
- plt.figure()用于设置画布大小
xticks 每隔几个点显示链接
plt.plot(x,y,color='g')
plt.xticks(range(0,365,20))
(一共365个点,每隔20个显示)
matplotlib.pyplot.figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None, frameon=True, FigureClass=<class 'matplotlib.figure.Figure'>, clear=False, **kwargs)[source]
'''
在画图之前首先设置figure对象,使得后面的图形输出在这块规定了大小的画布上。
num:用于返回指定 id 的figure对象,如果此参数没有提供,则一个新的figure对象将被创建。
figsize:用于设置画布的宽高,单位为英尺。
dpi:用于设置分辨率。
facecolor用于设置背景色
edgecolor用于设置边框颜色。
'''
plt.figure(figsize=[8,5]) #在绘图之前设置画布大小,宽为 8 英尺,高为 5 英尺
plt.plot(x, y) #绘制曲线
绘制多条曲线
同一个图中:
叠加使用plot
import matplotlib.pyplot as plt
from math import sin, cos, radians
x = range(0, 360)
y1 = [sin(radians(e)) for e in x]
y2 = [cos(radians(e)) for e in x]
plt.plot(x, y1, 'b-')
plt.plot(x, y2, 'r--')
plt.legend(['sin(x)', 'cos(x)'], loc='upper center')
plt.xlabel('x') #设置 x 轴文字标记
plt.ylabel('sin/cos') #设置 y 轴文字标记
plt.axis([0, 360, -1.0, 1.0]) #设置坐标范围
plt.show()

在两个坐标系中:
subplot()绘制子图
# 第一种:整个绘图区域被分成 nrows 行和 ncols 列,index 表示第几个图
subplot(nrows, ncols, index, **kwargs)
# 第二种:pos 是三位数的整数,其中第一位是行数,第二位是列数,第三位是子图的索引
subplot(pos, **kwargs)
# 第三种:添加子图 ax
subplot(ax)
# 返回(<Figure size 640x480 with 4 Axes>, array([[<AxesSubplot:>, <AxesSubplot:>],[<AxesSubplot:>, <AxesSubplot:>]], dtype=object))
plt.subplots(m,n)
import numpy as np
import matplotlib.pyplot as plt
x1 = np.linspace(0.0, 5.0)
x2 = np.linspace(0.0, 2.0)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
y2 = np.cos(2 * np.pi * x2)
plt.subplot(2, 1, 1) # 开始绘制子图 1 或 subplot(211) 被分为2行一列,接下来是第一幅子图
plt.plot(x1, y1, 'o-')
plt.title('A tale of 2 subplots')
plt.ylabel('Damped oscillation')
plt.subplot(2, 1, 2) # 开始绘制子图 2 或 subplot(212) 第二幅子图
plt.plot(x2, y2, '.-')
plt.xlabel('time (s)')
plt.ylabel('Undamped')
plt.show()

import numpy as np
import matplotlib.pyplot as plt
nums = np.arange(1, 101)
fig, axes = plt.subplots(2, 2)
ax1 = axes[0, 0]
ax2 = axes[0, 1]
ax3 = axes[1, 0]
ax4 = axes[1, 1]
ax1.plot(nums, nums)
ax2.plot(nums, -nums)
ax3.plot(nums, nums ** 2)
ax4.plot(nums, np.log(nums))
plt.show()

数组
在数学概念里,一个向量是一个 n 元组:
v=(_v_0,…,_vn_−1)
数组可以看做是向量的一般形式,可以有多个维度,如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YHUIUDzr-1656041024659)(https://cdn.nlark.com/yuque/__latex/778e585ba83f5a40ee669d13f8fdae6e.svg#card=math&code=A%20%3D%5Cbegin%7Bbmatrix%7D%0A1%20%26%202%20%26%203%20%20%20%20%20%20%5C%5C%0A4%20%26%205%20%26%206%20%20%20%20%20%20%5C%5C%0A7%20%26%208%20%26%209%0A%5Cend%7Bbmatrix%7D%0A&id=XWozK)]
A 是一个二维数组,而向量是一维数组。
数组和列表的主要差别如下:
- 列表可以包含任意类型的对象,一个数组只能包含同一类型的对象;
- 当成员是整数、浮点数或复数时,使用数组会更加高效。
Numpy创建数组在[numpy初体验中提到](https://www.yuque.com/docs/share/149c2509-72bb-4b8a-98ff-f077f3bc25c2?# 《Numpy初体验》)
常见的用array创建数组np.array([1,2,3,4])
其他函数:

ndarray2 = np.zeros((3, 3)) #产生3*3的数值为 0 的二维数组
ndarray3 = np.ones_like(ndarray2) # 按照 ndarray2 的形状创建数值为 1 的 3*3 数组
ndarray4 = np.arange(10) #产生 0-9 共 10 个元素
ndarray5 = np.arange(10, 20, 2) #产生数组 array([10, 12, 14, 16, 18]), 间隔为2
ndarray6 = np.linspace(2.0, 3.0, num=5) # 产生数组 array([ 2. , 2.25, 2.5 , 2.75, 3. ])
numpy中的数组处理函数

向量化
向量化指的是将需要循环才能操作数组的 Python 函数转化为直接操作整个数组的函数。向量化能够使得程序更短、可读性更好,且程序的运行速度更快。
# 抛物线向量化绘制
import numpy as np
import matplotlib.pyplot as plt
def f(x):
result = 3 * x ** 2 + 2 * x + 1
return result
x = np.linspace(0, 51, 51) # 区间[0,51] 样本数51
y = f(x)
plt.plot(x, y, 'r--')
plt.show()
向量化处理
以向量化阶跃函数为例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gKsPSdmW-1656041024663)(https://cdn.nlark.com/yuque/__latex/9cb15c037bba9bcf150693b3b6ab3ee5.svg#card=math&code=H%28x%29%3D%20%5Cbegin%7Bcases%7D%200%2C%20x%20%3E%200%20%5C%5C%5C%5C%0A%201%2Cx%20%5Cge0%20%20%5Cend%7Bcases%7D&id=amrQ3)]def H(x):
return (0 if x > 0 else 1)
上述代码只能处理数值型数据,在处理数组时会报错。
所以需要进行向量化处理:
有以下几种方案:
1.循环
def H1(x):
r = np.zeros(len(x)) # or r = x.copy()
for i in range(len(x)):
r[i] = H(x[i])
return r
2.向量化函数vectorize
H2 = np.vectorize(H)
3.用where
def H3(x):
return np.where(x < 0, 0.0, 1.0)
4.用例:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PTJntn3u-1656041024664)(https://cdn.nlark.com/yuque/__latex/2ab00272692bbc898ba5293b0cc449b4.svg#card=math&code=H%28x%29%3D%5Cbegin%7Bcases%7D%200%2Cx%3C0%20%5C%5C%5C%5C%20x%2C%200%20%5Cle%20x%20%3C%201%20%5C%5C%5C%5C%202-x%2C%20%201%20%5Cle%20x%20%3C%202%20%5C%5C%5C%5C%200%2C%20x%20%5Cge2%20%20%5Cend%7Bcases%7D&id=stowe)]
tips:
where可以嵌套
import numpy as np
import matplotlib.pyplot as plt
def f(x):
return np.where((x < 0) | (x >= 2), 0, (np.where(x < 1, x, 2 - x)))
t = np.linspace(-3, 5, 1000) # 区间[-3,5],样本数为1000
y = f(t)
plt.title('Plotting hat func in this plot')
plt.plot(t, y, 'b-') # 蓝色实线
plt.show()

图表
1.柱状图(bar)
bar函数绘制柱状图,参数如下:
matplotlib.pyplot.bar(x, height, width=0.8, bottom=None, *, align='center', data=None, **kwargs)
'''
x -- x轴标量序列,可以为列表、元组、一维数组
height -- 柱形高度
width -- 柱形宽度
alpha -- 颜色透明度
import numpy as np
import matplotlib.pyplot as plt
x_data = '2015 2014 2013 2012 2011 2010 2009 2008 2007 2006 \
2005 2004 2003 2002 2001 2000' # x轴数据
y = '12914 11826 12997 12306.41 12327.28 11406 10608 8378 8667.02 8052.78 6922.52 5744 4196 4336 4588 4751'
x_data = x_data.split()
y = y.split()
x_data.reverse()
y.reverse()
xlabels = x_data
y = [float(e) for e in y] # 将字符转变为float,不然做不了图
idx = range(16)
plt.xticks(idx, xlabels, rotation=45) # 横轴标签旋转45°
plt.yticks(range(4000, 13500, 1000)) # 坐标刻度[4000,13500] 刻度间隔1000
plt.ylim(4000, 13500) # 坐标轴范围[4000,13500]
plt.bar(idx, y, color='#800080')
plt.show()

堆积柱状图
用for循环或者列表解决
import matplotlib.pyplot as plt
import numpy as np
xstring = '2015 2014 2013 2012 2011 \
2010 2009 2008 2007 2006 \
2005 2004 2003 2002 2001 2000' # x轴标签
n = 6
ystring = [''] * n # y轴对应的6组数据
ystring[0] = '6793 6324 6237 5790.99 5357.1 5032 4681 3800 3863.9 3366.79 3167.66 2778 2359 2250 2170 2112'
ystring[1] = '6473 5933 5850 5429.93 4993.17 4725 4459 3576 3645.18 3119.25 2936.96 2608 2197 2092 2017 1948'
ystring[2] = '15157 12965 12591 11460.19 10993.92 10934 9662 7801 7471.25 6584.93 5833.95 5576 4145 4154 4348 4288'
ystring[3] = '12914 11826 12997 12306.41 12327.28 11406 10608 8378 8667.02 8052.78 6922.52 5744 4196 4336 4588 4751'
ystring[4] = '9566 9817 9777 9020.91 8488.21 7747 6871 5886 5773.83 5246.62 5021.75 3884 3675.14 3488.57 3273.53 3260.38'
ystring[5] = '4845 5177 4907 4305.73 4182.11 4099 3671 3219 3351.44 3131.31 2829.35 2235 2240.74 1918.83 2033.08 1864.37'
labels = ['Commercial housing', 'Residential commercial housing',
'high-end apartments', 'Office Building', 'Business housing', 'Others'] # 图例标签
colors = ['#ff7f50', '#87cefa', '#DA70D6', '#32CD32', '#6495ED', '#FF69B4'] # 指定颜色
bar_width = 0.8
x = xstring.split()
x.reverse()
xlabels = x
idx = np.arange(1, n * len(x), n)
for i in range(n):
y = ystring[i].split()
y.reverse()
y = [float(e) for e in y]
plt.bar(idx + i * bar_width, y, width=bar_width, color=colors[i])
plt.xticks(idx + bar_width * 2.5, xlabels, rotation=45) # idx + w*2.5 让每一年的数据居中对齐
plt.yticks(range(2000, 15000, 2000))
plt.xlim(-1, 98)
plt.ylim(1450, 15300)
plt.legend(labels, loc='upper left') # loc属性:调整图例位置 这里为左上方
plt.title('Selling Prices of Six Types of Housing')
plt.show()

2.饼图(pie)
matplotlib.pyplot.pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=None, radius=None, counterclock=True, wedgeprops=None, textprops=None, center=(0, 0), frame=False, rotatelabels=False, *, data=None)[source]
'''
饼图是逆时针绘制的,参数x表示绘制的序列数据,explode用于突出某个楔形(切片),具体值为偏移圆中心的占比,labels是一个字符串序列,用于给每个楔形打标签,colors用于指定楔形的颜色,autopct参数表示用数值标记楔形,可指定显示方式且标记在内部。
import matplotlib.pyplot as plt
labels = ['Frogs', 'Hogs', 'Dogs', 'Logs'] # 标签列表
sizes = [15, 30, 45, 10] # 绘制数据
explode = (0, 0.1, 0, 0) # 只突出第二个切块,偏移比例为0.1 (i.e. 'Hogs')
plt.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%',
shadow=True, startangle=90) # shadow表示添加阴影,startangle表示旋转角度 autopct 饼图显示数字
plt.axis('equal') # 用于显示为一个长宽相等的饼图
plt.show() #展示图像

figure()设置画布大小
matplotlib.pyplot.figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None, frameon=True, FigureClass=<class 'matplotlib.figure.Figure'>, clear=False, **kwargs)[source]
plt.figure(figsize=[14,5]) # 绘制之前设置
'''
参数num用于返回指定 id 的figure对象,如果此参数没有提供,则一个新的figure对象将被创建。参数figsize用于设置画布的宽高,单位为英尺。参数dpi用于设置分辨率。参数facecolor用于设置背景色,edgecolor用于设置边框颜色。
3.箱型图
plt.boxplot(x, notch=None, sym=None, vert=None, whis=None, positions=None, widths=None, patch_artist=None, meanline=None, showmeans=None, showcaps=None, showbox=None, showfliers=None, boxprops=None, labels=None, flierprops=None, medianprops=None, meanprops=None, capprops=None, whiskerprops=None)
'''
x:指定要绘制箱线图的数据;
notch:是否是凹口的形式展现箱线图,默认非凹口;
sym:指定异常点的形状,默认为+号显示;
vert:是否需要将箱线图垂直摆放,默认垂直摆放;
whis:指定上下须与上下四分位的距离,默认为1.5倍的四分位差;
positions:指定箱线图的位置,默认为[0,1,2…];
widths:指定箱线图的宽度,默认为0.5;
patch_artist:是否填充箱体的颜色;
meanline:是否用线的形式表示均值,默认用点来表示;
showmeans:是否显示均值,默认不显示;
showcaps:是否显示箱线图顶端和末端的两条线,默认显示;
showbox:是否显示箱线图的箱体,默认显示;
showfliers:是否显示异常值,默认显示;
boxprops:设置箱体的属性,如边框色,填充色等;
labels:为箱线图添加标签,类似于图例的作用;
filerprops:设置异常值的属性,如异常点的形状、大小、填充色等;
medianprops:设置中位数的属性,如线的类型、粗细等;
meanprops:设置均值的属性,如点的大小、颜色等;
capprops:设置箱线图顶端和末端线条的属性,如颜色、粗细等;
whiskerprops:设置须的属性,如颜色、粗细、线的类型等;
4.散点图
matplotlib.pyplot.scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, verts=None, edgecolors=None, , data=None, *kwargs)
'''
x, y : 相同长度的数组,数组大小(n,),也就是绘制散点图的数据;
s:绘制点的大小,可以是实数或大小为(n,)的数组, 可选的参数 ;
c:绘制点颜色, 默认是蓝色'b' , 可选的参数 ;
marker:表示的是标记的样式,默认的是'o' , 可选的参数 ;
cmap:当c是一个浮点数数组的时候才使用, 可选的参数 ;
norm:将数据亮度转化到0-1之间,只有c是一个浮点数的数组的时候才使用, 可选的参数 ;
vmin , vmax:实数,当norm存在的时候忽略。用来进行亮度数据的归一化 , 可选的参数 ;
alpha:实数,0-1之间, 可选的参数 ;
linewidths:标记点的长度, 可选的参数 ;
综合示例
data.csv

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
plt.rcParams["font.sans-serif"] = "SimHei"
plt.rcParams["axes.unicode_minus"] = False
df_water = pd.read_csv('2001-2017年北京市水资源情况信息.csv', engine="python")
df_water = df_water.T # 转置
df_water.columns = pd.Series([i.replace(" ","") for i in list(df_water.iloc[0,:])])
df_water = df_water.iloc[1:,:] # 出去第一行的文字说明
d = {}
for i in list(df_water.columns):
d[i]= "float"
df_water = df_water.astype(d)
#确定画布大小为12*12英寸,分辨率为100
fig = plt.figure(figsize=(12,12),dpi=100)
#添加第一幅子图:全年水资源量、地表水资源量、地下水资源量
ax1 = fig.add_subplot(2,2,1)
plt.title("全年水资源量折线图")
plt.xlabel("年份")
plt.ylabel("亿立方米")
plt.plot(df_water.index, df_water.iloc[:,0], 'r-')
plt.plot(df_water.index, df_water.iloc[:,1], 'g--')
plt.plot(df_water.index, df_water.iloc[:,2], 'b:')
plt.xticks(range(0,18,2),np.array(df_water.index)[range(0,18,2)],rotation=45)
# plt.xticks(range(0,18,2),range(2001, 2018, 2), rotation=45)
#x轴刻度为年份,隔2年显示,45度斜显示
plt.yticks([0,5,10,15,20,25,30,35,40])
# plt.yticks(range(0, 41, 5), rotation=45)
#y轴刻度为0至40,相隔5
plt.legend(df_water.columns[0:3])
##添加第二幅子图:人均水资源(单位:立方米/人)
ax2 = fig.add_subplot(2,2,2)
plt.title("人均水资源量散点图")
plt.xlabel("年份")
plt.ylabel("立方米/人")
plt.scatter(df_water.index, df_water.iloc[:,3],marker='o', c="blue") # 散点图
#绘制点的类型为circle('o'),颜色为蓝色
plt.xticks(range(0,18,2),np.array(df_water.index)[range(0,18,2)],rotation=45)
# plt.xticks(range(0, 18, 2), range(2001, 2018, 2), rotation=45)
#x轴刻度为年份,隔2年显示,45度斜显示
plt.yticks([i for i in range(100,210,10)]) #列表的推导式
# plt.yticks(range(100, 201, 10))
#y轴刻度为100至200,相隔10
plt.legend(["人均水资源(立方米/人)"])
##添加第三幅子图:2017年农业用水、工业用水、生活用水、生态环境用水饼图
ax3 = fig.add_subplot(2,2,3)
plt.title("2017年用水量饼图")
plt.pie(df_water.iloc[-1,10:14],explode=[0.01,0.01,0.01,0.01], labels=list(df_water.columns[10:14]), \
autopct="%1.2f%%") #绘制饼图
#设置饼图中各个饼之间的间距均为0.01,百分比显示格式为小数点后保留2位;
##添加第四幅子图:2001-2017年万元地区生产总值耗水量(立方米)
ax3 = fig.add_subplot(2,2,4)
plt.title("2001-2017年万元地区生产总值耗水量箱线图")
plt.boxplot(df_water.iloc[:,-1], notch=True, labels=["万元地区生产总值耗水量(立方米)"], \
meanline=True)
#凹口的形式展现箱线图,用线的形式表示均值
'''
ex = [0.01, 0.01, 0.01, 0.01]
plt.pie(df_water.iloc[-1, 10:14], explode=ex, autopct='%1.2f%%',labels=df_water.columns[10:14])
'''
plt.savefig("2001-2017年北京市水资源情况信息0.png")

GitCode 天启AI是一款由 GitCode 团队打造的智能助手,基于先进的LLM(大语言模型)与多智能体 Agent 技术构建,致力于为用户提供高效、智能、多模态的创作与开发支持。它不仅支持自然语言对话,还具备处理文件、生成 PPT、撰写分析报告、开发 Web 应用等多项能力,真正做到“一句话,让 Al帮你完成复杂任务”。
更多推荐
所有评论(0)