学习笔记来源于matplotlib官网:Matplotlib 文档 — Matplotlib 3.7.2 文档
因为使用的jupyter所以直接plot()就能看到图,而使用pycharm的需要加plt.show()
目录
1. 导入
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
2. 绘图基础(参考Matplotlib教程顺序)
2.1. jupyter内核挂掉的解决方式
(1)绘图时,Jupyter Notebook调用matplotlib.pyplot服务似乎挂掉了。挂掉的服务解决方法可能为
"""来源:https://blog.csdn.net/yufanwenshu/article/details/122033560"""
import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'TRUE'
(2)matplot版本不对,此时需要检查版本并重新安装
(3)最简单的方法,试试重启呢?(万物皆可重启)
(4)
最终看到有一位博主说是matplotlib安装方式的问题。我使用的是在anaconda中新建的虚拟环境,matplotlib是通过conda安装的。博主说他通过pip的uninstall和install先卸载再安装matplotlib最终解决了问题。我效仿尝试,但是使用pip uninstall matplotlib一直报错。最终我直接在该虚拟环境下的Lib\site-packages目录下删除了matplotlib的相关文件夹,再使用pip install matplotlib 成功安装了matplotlib,再打开笔记本运行,问题解决。
————————————————
原文链接:https://blog.csdn.net/yufanwenshu/article/details/122033560
2.2. 制作图形框
(1)用fig和ax来接收subplots传回来的两个变量值
fig, ax = plt.subplots()
(2)subplots:创建一个图形和一组子图
①subplots的参数
matplotlib.pyplot.subplots(nrows=1, ncols=1, *, sharex=False, sharey=False, squeeze=True, width_ratios=None, height_ratios=None, subplot_kw=None, gridspec_kw=None, **fig_kw)
②subplots的返回值
(3)plot:将x与y绘制为线条(lines)或标记(marks)
①plot的参数
Axes.plot(*args, scalex=True, scaley=True, data=None, **kwargs)[source]
②plot示例
ax.plot([1, 2, 3, 4], [1, 4, 2, 3])
此时plot画出的图为散点(1,1),(2,4),(3,2),(4,3)。若plot(x,y)其中的x与y为数学函数则可以画出连续的函数图像
③plot的返回值:一个2D列表
(4)figure:创建新图形或激活现有图形
①figure的参数
matplotlib.pyplot.figure(num=None, figsize=None, dpi=None, *, facecolor=None, edgecolor=None, frameon=True, FigureClass=<class 'matplotlib.figure.Figure'>,clear=False, **kwargs)[来源]
②figure的返回值:Figure
(5)图形组件
2.3. 空白图形框
(1)
fig = plt.figure() # an empty figure with no Axes
(2)不含参就默认一个
fig, ax = plt.subplots() # a figure with a single Axes
(3)⭐相当于这是创建了四个子图,而不是高宽为2*2的坐标轴
fig, axs = plt.subplots(2, 2) # a figure with a 2x2 grid of Axes
(4)额
# a figure with one axes on the left, and two on the right:
fig, axs = plt.subplot_mosaic([['left', 'right_top'],
['left', 'right_bottom']])
2.4. 编码样式的显式接口和隐式接口
(1)显式接口:显式创建图形和轴,并对其调用方法( “面向对象 (OO) 样式”)(OO??)
①示例代码
x = np.linspace(0, 2, 100) # Sample data.
# Note that even in the OO-style, we use `.pyplot.figure` to create the Figure.
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
ax.plot(x, x, label='linear') # Plot some data on the axes.
ax.plot(x, x**2, label='quadratic') # Plot more data on the axes...
ax.plot(x, x**3, label='cubic') # ... and some more.
ax.set_xlabel('x label') # Add an x-label to the axes.
ax.set_ylabel('y label') # Add a y-label to the axes.
ax.set_title("Simple Plot") # Add a title to the axes.
ax.legend() # Add a legend.
(2)隐式接口:依靠 pyplot 隐式创建和管理图形和轴,以及使用 pyplot 函数进行绘图
①示例代码
x = np.linspace(0, 2, 100) # Sample data.
plt.figure(figsize=(5, 2.7), layout='constrained')
plt.plot(x, x, label='linear') # Plot some data on the (implicit) axes.
plt.plot(x, x**2, label='quadratic') # etc.
plt.plot(x, x**3, label='cubic')
plt.xlabel('x label')
plt.ylabel('y label')
plt.title("Simple Plot")
plt.legend()
(3)区别
①乍一看还以为没区别,所以复杂度感觉差不太多
②显式plt.subplots要返回两个参数fig和ax,而隐式plt.figure不用返回
③纯纯前面的类不一样吧一个ax.一个plt.,后面接的参数都一样
④动手学深度学习都用的隐式
(4)结果图(两个画出来都是一样的)
2.5. 函数的程序化
(1)自定义函数罢了
(2)自定义画图函数示例
①代码
def my_plotter(ax, data1, data2, param_dict):
out = ax.plot(data1, data2, **param_dict)
return out
data1, data2, data3, data4 = np.random.randn(4, 100) # make 4 random data sets
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(5, 2.7))
my_plotter(ax1, data1, data2, {'marker': 'x'})
my_plotter(ax2, data3, data4, {'marker': 'o'})
②结果展示
(3)...但是这个也可以不自定义
①代码(⭐这里需要删去参数里的ax1,ax2因为本身ax.plot没有这个参数,而且需要将上面表示字典的{'marker': 'x'}改为marker='x'才能成功绘图)
data1, data2, data3, data4 = np.random.randn(4, 100) # make 4 random data sets
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(5, 2.7))
ax1.plot(data1,data2,marker='x')
ax2.plot(data3,data4,marker='o')
②结果展示(实际上和上面那个是一模一样的东西只是因为两个代码都是随机所以图显示得不一样)
2.6. 绘图造型
(1)示例
①代码
fig, ax = plt.subplots(figsize=(5, 2.7))
x = np.arange(len(data1))
ax.plot(x, np.cumsum(data1), color='Cyan', linewidth=3, linestyle='--')
l, = ax.plot(x, np.cumsum(data2), color='pink', linewidth=2)
l.set_linestyle(':')
②其中第四行l, =是接收了返回值,第一个返回值赋值给I,后面的并未命名,不占用变量空间,和I,_=同义
③这个第二行的data1和data2是2.6里random的
④结果展示
2.7. 颜色,线宽,线型,刻字和标记大小
(1)颜色
①代码
fig, ax = plt.subplots(figsize=(5, 2.7))
ax.scatter(data1, data2, s=50, facecolor='pink', edgecolor='black')
②结果展示
(2)线宽,线型,刻字和标记大小
①代码
fig, ax = plt.subplots(figsize=(5, 2.7))
ax.plot(data1, 'o', label='data1')
ax.plot(data2, 'd', label='data2')
ax.plot(data3, 'v', label='data3')
ax.plot(data4, 's', label='data4',color='pink')
"""刻字 就是那个小框框标记"""
ax.legend()
可知color不加会系统直接默认,但是也可以自己加一个
②结果展示
2.8. 标记绘图
(1)轴标签和文本
①代码
mu, sigma = 115, 15
x = mu + sigma * np.random.randn(10000)
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
"""这是个直方图"""
n, bins, patches = ax.hist(x, 50, density=True, facecolor='pink',edgecolor='black',alpha=0.75)
ax.set_xlabel('Length [cm]')
ax.set_ylabel('Probability')
ax.set_title('Aardvark lengths\n (not really)')
"""Axes.text(x, y, s, fontdict=None, **kwargs),将s添加到(x,y)处"""
ax.text(75, .025, r'$\mu=115,\ \sigma=15$')
"""xmin, xmax, ymin, ymax = axis([xmin, xmax, ymin, ymax])"""
ax.axis([55, 175, 0, 0.03])
"""配置轴线,TRUE为轴线存在"""
ax.grid(True)
②结果展示
③将关键词参数传递到文本函数中
(2)数学表达式的嵌入(⭐仅在作图中适用,print不适用)
①直接输入的代码和结果
# plain text
plt.title('alpha > beta')
②数学表达式的代码和结果
# math text
plt.title(r'$\alpha > \beta$')
数学文本应放置在一对美元符号($)之间。要做到 易于显示货币值,例如,“$100.00”,如果是单个美元符号 存在于整个字符串中,它将逐字显示为美元 标志。这是与常规TeX的一个小变化,在常规TeX中,美元登录 非数学文本必须进行转义 ('$')。
③上标和下标(偷个懒截图了)
④由于内容太多摘抄不完需要可以移步:Writing mathematical expressions — Matplotlib 3.7.2 documentation
(3)附注箭头
①ax.annotate
②参数
Axes.annotate(text, xy, xytext=None, xycoords='data', textcoords=None, arrowprops=None, annotation_clip=None, **kwargs)
③代码示例
fig, ax = plt.subplots(figsize=(5, 2.7))
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2 * np.pi * t)
line, = ax.plot(t, s, lw=2,color='pink')
ax.annotate('local max', xy=(2, 1), xytext=(3, 1.5),
arrowprops=dict(facecolor='Cyan', shrink=0.05))
ax.set_ylim(-2, 2)
④结果展示
2.9. 尺度
(1)更改为非线性刻度
①代码示例
fig, axs = plt.subplots(1, 2, figsize=(5, 2.7))
xdata = np.arange(len(data1))
data = 10**data1
axs[0].plot(xdata, data,color='pink')
axs[1].set_yscale('log')
axs[1].plot(xdata, data,color='pink')
②结果展示
2.10. 交互模式
(1)plt.ion():将原本默认阻塞的画图模式变更为交互模式(即展示动态图或多个窗口)(在交互模式下,plt.plot(x)或plt.imshow(x)是直接出图像,不需要plt.show(),而阻塞模式下打开一个窗口以后必须关掉才能打开下一个新的窗口)
(2)plt.ioff():关闭交互模式
(3)代码
plt.ion() # 打开交互模式
# 同时打开两个窗口显示图片
plt.figure() #图片一
plt.imshow(i1)
plt.figure() #图片二
plt.imshow(i2)
# 显示前关掉交互模式
plt.ioff()
plt.show()
(4)来源于:Python中使用plt.ion()和plt.ioff()画动态图_Yale曼陀罗的博客-CSDN博客
3. 2D绘图种类
3.1. 普通绘图
(1)plot
①示例代码
x = np.linspace(0, 10, 100)
y = 4 + 2 * np.sin(2 * x)
fig, ax = plt.subplots()
ax.plot(x, y, linewidth=2.0,color='pink')
ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
ylim=(0, 8), yticks=np.arange(1, 8))
plt.show()
②结果展示
(2)matplotlib在代码上方给出了如下代码,但我在jupyter里测试有无这句画出来的图均一致,故去掉此行代码
plt.style.use('_mpl-gallery')
3.2. 散点图
(1)ax.scatter():具有不同标记大小和颜色的x与y的散点图
①示例代码与结果
np.random.seed(19680801) # seed the random number generator.
data = {'a': np.arange(50),
'c': np.random.randint(0, 50, 50),
'd': np.random.randn(50)}
data['b'] = data['a'] + 10 * np.random.randn(50)
data['d'] = np.abs(data['d']) * 100
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
ax.scatter('a', 'b', c='c', s='d', data=data)
ax.set_xlabel('entry a')
ax.set_ylabel('entry b')
②ax.scatter的参数
Axes.scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, *, edgecolors=None, plotnonfinite=False, data=None, **kwargs)
③ax.scatter的返回值:PathCollection
3.3. 柱状图
(1)ax.bar:制作一个柱状图
①参数
Axes.bar(x, height, width=0.8, bottom=None, *, align='center', data=None, **kwargs)
②代码示例
x = 0.5 + np.arange(8)
y = [4.8, 5.5, 3.5, 4.6, 6.5, 6.6, 2.6, 3.0]
fig, ax = plt.subplots()
"""这一行在下文中会被多次替换为其他绘图函数"""
ax.bar(x, y, width=0.8, edgecolor="black",facecolor='pink', linewidth=0.5)
ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
ylim=(0, 8), yticks=np.arange(1, 8))
plt.show()
③结果展示
这张图其实说明了代码中的width并不会改变一个数据占一个位的事实,因为如果把width改成2并不会意味着数据的间隔变成2,而是如下惨状:
3.4. 针状图
(1)ax.stem:创建针状图(这都不用说了直接把柱状图的函数代码改了就好了)
①参数
Axes.stem(*args, linefmt=None, markerfmt=None, basefmt=None, bottom=0, label=None, use_line_collection=<deprecated parameter>, orientation='vertical', data=None)
②代码(仅仅改了上文那一行)
ax.stem(x, y)
③结果展示
3.5. 梯状图
(1)ax.step:制作阶梯图(同上 只改一行就好了)
①参数
Axes.step(x, y, *args, where='pre', data=None, **kwargs)[source]
②代码
ax.step(x, y, linewidth=2.5)
③结果展示
3.6. 堆栈图
(1)ax.stackplot:画出一个堆栈区域图(还没能太看懂咋画出来的,可能还没学numpy.vstack吧)
①参数
Axes.stackplot(x, *args, labels=(), colors=None, baseline='zero', data=None, **kwargs)
②代码示例
x = np.arange(0, 10, 2)
ay = [0, 1.25, 2, 2.75, 3]
by = [5, 1, 1, 1, 1]
cy = [2, 1, 2, 1, 2]
y = np.vstack([ay, by, cy])
fig, ax = plt.subplots()
ax.stackplot(x, y)
ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
ylim=(0, 8), yticks=np.arange(1, 8))
plt.show()
③结果展示
3.7. 直方图
(1)好像柱状图是喜欢比较不同的东西,但是直方图是比较同一种类型的数据差异(如学生成绩分布)。然后直方图一般是连续的数据,而柱状图是离散的。科普入口:能分清直方图和柱状图,你就是图表届的“头号”玩家 - 知乎 (zhihu.com)
(2)ax.hist:计算并绘制直方图(但是这个很奇怪啊为什么不能在bar上直接改??)
①代码
np.random.seed(1)
x = 4 + np.random.normal(0, 1.5, 200)
fig, ax = plt.subplots()
ax.hist(x, bins=8, linewidth=0.5, edgecolor="white")
ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
ylim=(0, 56), yticks=np.linspace(0, 56, 9))
plt.show()
②结果展示
3.8. 箱线图
(1)ax.boxplot:绘制一个箱线图
①参数
Axes.boxplot(x, notch=None, sym=None, vert=None, whis=None, positions=None, widths=None, patch_artist=None, bootstrap=None, usermedians=None, conf_intervals=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, manage_ticks=True, autorange=False, zorder=None, capwidths=None, *, data=None)
②代码示例
np.random.seed(10)
D = np.random.normal((3, 5, 4), (1.25, 1.00, 1.25), (100, 3))
fig, ax = plt.subplots()
VP = ax.boxplot(D, positions=[2, 4, 6], widths=1.5, patch_artist=True,
showmeans=False, showfliers=False,
medianprops={"color": "Cyan", "linewidth": 0.5},
boxprops={"facecolor": "pink", "edgecolor": "white",
"linewidth": 0.5},
whiskerprops={"color": "black", "linewidth": 1.5},
capprops={"color": "green", "linewidth": 1.5})
ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
ylim=(0, 8), yticks=np.arange(1, 8))
plt.show()
③结果展示(配了个稍微死亡的颜色...)
可以见得这个x轴只有三个数似乎有点问题,之后可以去改改
3.9. 误差线图
(1)ax.errorbar:将x与y绘制为带有附加误差线的线条和标记
①参数
Axes.errorbar(x, y, yerr=None, xerr=None, fmt='', ecolor=None, elinewidth=None, capsize=None, barsabove=False, lolims=False, uplims=False, xlolims=False, xuplims=False, errorevery=1, capthick=None, *, data=None, **kwargs)[source]
②代码示例
np.random.seed(1)
x = [2, 4, 6]
y = [3.6, 5, 4.2]
yerr = [0.9, 1.2, 0.5]
fig, ax = plt.subplots()
ax.errorbar(x, y, yerr, fmt='o', linewidth=2, capsize=6,color='pink')
ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
ylim=(0, 8), yticks=np.arange(1, 8))
plt.show()
③结果展示
3.10. 2D直方图(长得很像回归啊)
(1)ax.hist2d:
①参数
Axes.hist2d(x, y, bins=10, range=None, density=False, weights=None, cmin=None, cmax=None, *, data=None, **kwargs)[source]
②代码示例
np.random.seed(1)
x = np.random.randn(5000)
y = 1.2 * x + np.random.randn(5000) / 3
fig, ax = plt.subplots()
ax.hist2d(x, y, bins=(np.arange(-3, 3, 0.1), np.arange(-3, 3, 0.1)))
ax.set(xlim=(-2, 2), ylim=(-3, 3))
plt.show()
③结果展示
不知道为什么画出来这个临时文件报错了啊?
3.11. 饼状图
(1)ax.pie:绘制饼图
①参数
Axes.pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=0, radius=1, counterclock=True, wedgeprops=None, textprops=None, center=(0, 0), frame=False, rotatelabels=False, *, normalize=True, hatch=None, data=None)
②代码示例(这个Blues不能改成Pinks挺让人伤心的)
x = [1, 2, 3, 4]
colors = plt.get_cmap('Blues')(np.linspace(0.2, 0.7, len(x)))
fig, ax = plt.subplots()
ax.pie(x, colors=colors, radius=3, center=(4, 4),
wedgeprops={"linewidth": 1, "edgecolor": "white"}, frame=True)
ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
ylim=(0, 8), yticks=np.arange(1, 8))
plt.show()
③结果展示
4. 3D绘图种类
4.1. 3D散点图
(1)ax.scatter(x,y,z)(实际上和刚刚的是一个函数!只是参数不一样就能画出3D)
①代码示例
np.random.seed(19680801)
n = 100
rng = np.random.default_rng()
xs = rng.uniform(23, 32, n)
ys = rng.uniform(0, 100, n)
zs = rng.uniform(-50, -25, n)
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.scatter(xs, ys, zs)
ax.set(xticklabels=[],
yticklabels=[],
zticklabels=[])
plt.show()
②结果展示
4.2. 3D表面
(1)ax.plot_surface
①代码示例
from matplotlib import cm
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
"""从坐标向量返回坐标矩阵的列表"""
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.plot_surface(X, Y, Z, vmin=Z.min() * 2, cmap=cm.Blues)
ax.set(xticklabels=[],
yticklabels=[],
zticklabels=[])
plt.show()
②需要注意的是,这里引入了新的类cm,cm.Blues就是引入的线性分段颜色图
③结果展示
4.3. 3D线框图
(1)ax.plot_wireframe
①代码示例
from mpl_toolkits.mplot3d import axes3d
X, Y, Z = axes3d.get_test_data(0.05)
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)
ax.set(xticklabels=[],
yticklabels=[],
zticklabels=[])
plt.show()
②需要注意的是,这里引入了新的类axes3d
③结果展示