python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > python matplotlib绘图

python matplotlib绘图详解大全(非常详细!)

作者:WDLOVELONGLONG

这篇文章主要给大家介绍了关于python matplotlib绘图详解的相关资料,matplotlib是python中用于绘制各种图像的模块,功能十分强大,通常与pandas模块搭配使用,可以生成各种样视的图片,用于数据的分析和展示,需要的朋友可以参考下

一、图形绘制大全

1.1 2D图形绘制

1.1.1 绘制单线图形

通过定义队列绘制单线图:

scale = range(100)
x = [(2 * math.pi * i) / len(scale) for i in scale]
y = [math.cos(i) for i in x]
plt.plot(x, y)
plt.show()

Matplotlib  使用的数据可以有不同来源,接下来,我们以使用  Numpy  获取的数据为例,绘制  [-10,10]  区间内的曲线,如以下:

x = np.linspace(-10, 10, 800)
y = x ** 3 + 5 * x - 10
plt.plot(x, y)
plt.show()

plot() 的用法如下:

pythonCopy code
plot(x, y, linestyle=None, marker=None, color=None, label=None, **kwargs)

其中,参数的含义如下:

通过传递 x y 的数据,你可以使用 plot() 方法绘制一条线。 linestyle 参数可选,用于控制线条样式; marker 参数可选,用于显示数据点的标记; color 参数可选,用于指定线条和标记的颜色; label 参数可选,用于添加线条的标签,用于图例显示。

绘制多条线时,可以多次调用 plot() 方法,每次传递不同的 x y 数据,并根据需要设置不同的样式和颜色。当绘制多条线时,你可以使用 label 参数为每条线添加标签,然后使用 plt.legend() 来显示图例。

1.1.2 绘制多线图

很多时候需要对比多组数据,以发现数据间的异同,此时就需要在一张图片上绘制多条曲线——多曲线图,示例如下:

#绘制多线图
x = np.linspace(0.1, 2 * np.pi, 100)
y_1 = x
y_2 = np.square(x)
y_3 = np.log(x)
y_4 = np.sin(x)
plt.plot(x,y_1)
plt.plot(x,y_2)
plt.plot(x,y_3)
plt.plot(x,y_4)
plt.show()

一条曲线的绘制需要调用一次  plt.plot() ,而  plt.show()  只需调用一次。这种延迟呈现机制是  Matplotlib  的关键特性,我们可以在代码中的任何地方调用绘图函数,但只有在调用  plt.show()  时才会渲染显示图形。

比如:

def plot_func(x, y):
x_s = x[1:] - y[:-1]
y_s = y[1:] - x[:-1]
plt.plot(x[1:], x_s / y_s)
x = np.linspace(-5, 5, 200)
y = np.exp(-x ** 2)
plt.plot(x, y)
plot_func(x, y)
plt.show()

尽管其中一个  plt.plot()  是在  plot_func  函数中调用的,它对图形的呈现没有任何影响,因为  plt.plot()  只是声明了我们要呈现的内容,但还没有执行渲染。因此可以使用延迟呈现特性结合  for  循环、条件判断等语法完成复杂图形的绘制,同时也可以在同一张图中组合不同类型的统计图。

1.1.3 读取文件中的数据绘制图形

很多情况下数据都是存储于文件中,因此,需要首先读取文件中的数据,再进行绘制,说明起见,以  .txt  文件为例,其他诸如  Excel CSV文件  等同样可以进行读取,并用于可视化绘制。

例如:

x, y = [], []
for line in open('data.txt', 'r'):
values = [float(s) for s in line.split()]
x.append(values[0])
y.append(values[1])
plt.plot(x, y)
plt.show()

1.1.4 绘制散点图

scatter方法通常是由数据可视化库(如Matplotlib或Seaborn)提供的一个函数,用于绘制散点图:

Matplotlib中scatter方法的参数和用法:

matplotlib.pyplot.scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, edgecolors=None)

参数解释:

data = np.random.rand(1000, 2)  #1000行、2列的随机数数组,符合均匀分布
plt.scatter(data[:,0], data[:,1])
plt.show()

1.1.5 绘制条形图

条形图具有丰富的表现形式,常见的类型包括单组条形图,多组条形图,堆积条形图和对称条形图等

1.1.5.1 单条条形图

条形图的每种表现形式都可以绘制成垂直条形图或水平条形图。

1、垂直条形图

plt.bar 是Matplotlib库中用于绘制条形图的方法。它可以将数据以条形的形式展示,非常适合用于显示不同类别或组之间的比较。

使用 plt.bar 的一般语法如下:

pythonCopy code
plt.bar(x, height, width=0.8, align='center', **kwargs)

其中,参数的意义如下:

一旦调用了 plt.bar 来绘制条形图,可以使用 plt.xlabel plt.ylabel plt.title 等方法来添加坐标轴标签和图标题,以及其他Matplotlib方法来美化图形。

data = [10., 20., 5., 15.]
plt.bar(range(len(data)), data, width=0.5)
plt.show()

2、水平条形图

如果更喜欢水平条形外观,就可以使用  plt.barh()  函数,在用法方面与  plt.bar()  基本相同,但是修改条形宽度(或者在水平条形图中应该称为高度),需要使用参数  height

下面是 plt.barh() 方法的一般语法:

plt.barh(y, width, height=0.8, left=None, **kwargs)

其中,参数的意义如下:

data = [10., 20., 5., 15.]
plt.barh(range(len(data)), data, height=0.5)
plt.show()

1.1.5.2 多组条形图

当出现比较的情况时,可以绘制多组条形图:

data = [[10., 20., 30., 20.],[40., 25., 53., 18.],[6., 22., 52., 19.]]
x = np.arange(4)
plt.bar(x + 0.00, data[0], color = 'b', width = 0.25)
plt.bar(x + 0.25, data[1], color = 'g', width = 0.25)
plt.bar(x + 0.50, data[2], color = 'r', width = 0.25)
plt.show()

同理,使用barh方法绘制多组水平条形图:

data = [[10., 20., 30., 20.],[40., 25., 53., 18.],[6., 22., 52., 19.]]
x = np.arange(4)
plt.barh(x + 0.00, data[0], color = 'b', height = 0.25)
plt.barh(x + 0.25, data[1], color = 'g', height = 0.25)
plt.barh(x + 0.50, data[2], color = 'r', height = 0.25)
plt.show()

1.1.5.3 堆积条形图

通过使用  plt.bar()  函数中的可选参数,可以绘制堆积条形图, plt.bar()  函数的可选参数  bottom  允许指定条形图的起始值。

y_1 = [3., 25., 45., 22.]
y_2 = [6., 25., 50., 25.]
x = range(4)
plt.bar(x, y_1, color = 'b')
plt.bar(x, y_2, color = 'r', bottom = y_1)
plt.show()

如果想要绘制水平的堆积条形图,则需要使用left来指定其实位置:

y_1 = [3., 25., 45., 22.]
y_2 = [6., 25., 50., 25.]
x = range(4)
​
# # 对y_1和y_2进行累加
# y_1_cumsum = np.cumsum(y_1)
# y_2_cumsum = np.cumsum(y_2)
​
plt.barh(x, y_1, color='b', label='y_1')
plt.barh(x, y_2, color='r', left=y_1, label='y_2')
​
plt.legend()
plt.show()

可以结合  for  循环,利用延迟呈现机制可以堆叠更多的条形:

data = np.array([[5., 30., 45., 22.], [5., 25., 50., 20.], [1., 2., 1., 1.]])
x = np.arange(data.shape[1])
for i in range(data.shape[0]):
plt.bar(x, data[i], bottom = np.sum(data[:i], axis = 0))
plt.show()

1.1.5.4 对称条形图

当我们想要绘制不同年龄段的男性与女性数量的对比时,一个简单且有用的技巧是对称绘制两个条形图:

w_pop = np.array([5., 30., 45., 22.])
m_pop = np.array( [5., 25., 50., 20.])
x = np.arange(4)
plt.barh(x, w_pop)
plt.barh(x, -m_pop)
plt.show()

1.1.4 饼图

饼图可以用于对比数量间的相对关系, plt.pie()  函数将一系列值作为输入,将值传递给  Matplolib ,它就会自动计算各个值在饼图中的相对面积,并进行绘制:

使用 plt.pie() 的一般语法如下:

pythonCopy code
plt.pie(x, explode=None, labels=None, colors=None, autopct=None, shadow=False, startangle=0, **kwargs)

其中,参数的意义如下:

一旦调用了 plt.pie() 来绘制饼图,你可以使用 plt.axis('equal') 来保证饼图是圆形的,使用 plt.legend() 来显示图例。

data = [10, 15, 30, 20]
plt.pie(data,explode = [0.1,0.1,0.1,0.1],shadow=True)
plt.show()

1.1.5 直方图

直方图是概率分布的图形表示。事实上,直方图只是一种特殊的条形图。我们可以很容易地使用  Matplotlib  的条形图函数,并进行一些统计运算来生成直方图。但是,鉴于直方图的使用频率非常高,因此  Matplotlib  提供了一个更加方便的函数—— plt.hist() 。  plt.hist()  函数的作用是:获取一系列值作为输入。值的范围将被划分为大小相等的范围(默认情况下数量为  10 ),然后生成条形图,一个范围对应一个条柱,一个条柱的高度是相应范围内中的值的数量,条柱的数量由可选参数  bins 确定。

使用 plt.hist() 的一般语法如下:

pythonCopy code
plt.hist(x, bins=None, range=None, density=False, cumulative=False, color=None, edgecolor=None, **kwargs)

其中,参数的意义如下:

一旦调用了 plt.hist() 来绘制直方图,你可以使用 plt.xlabel() plt.ylabel() plt.title() 等方法来添加坐标轴标签和图标题,使用 plt.legend() 来显示图例,

data1 = np.random.rand(1024)
plt.hist(data1, bins=10, alpha=0.6, label='Data 1', histtype='bar', rwidth=0.8)
plt.xlabel('Value')
plt.ylabel('Frequency')
plt.title('Histogram with Gap between Bars')
plt.legend()
plt.show()

如果要在绘制多个直方图时,让它们之间有间距,可以使用 plt.hist() 方法的 histtype 参数。 histtype 参数用于指定直方图的类型,包括'bar'(默认)、'barstacked'和'step'等。

对于绘制多个直方图,并希望它们之间有间距,可以选择使用'bar'或'barstacked'类型,并将 alpha 参数设置为小于1的值,从而使得直方图之间透明,从而呈现出间距的效果。

在上面的代码中,使用了 histtype='bar' alpha=0.6 参数来设置直方图类型为'bar'并使得直方图之间有间距。同时,我们还设置了 rwidth=0.8 来控制直方图的宽度,以使得直方图在水平方向上有间距。

1.1.6 箱形图

箱线图将会显示数据的五数概括:最小值、下四分位数、中位数、上四分位数、最大值,以及可能的异常值。

使用 plt.boxplot(data) 的一般语法如下:

plt.boxplot(data, notch=None, sym=None, vert=None, whis=None, positions=None, widths=None, patch_artist=None, **kwargs)

其中,参数的意义如下:

一旦调用了 plt.boxplot(data) 来绘制箱线图,你可以使用 plt.xlabel() plt.ylabel() plt.title() 等方法来添加坐标轴标签和图标题,使用 plt.xticks() plt.yticks() 来自定义刻度标签

示例:

data = np.random.randn(100)
# 绘制箱线图
plt.boxplot(data)
# 添加标题和标签
plt.title('Box Plot Example')
plt.ylabel('Value')
# 显示箱线图
plt.show()

要在单个图形中绘制多个箱形图,对每个箱形图调用一次 plt.boxplot() 是不可行。它会将所有箱形图画在一起,形成一个混乱的、不可读的图形。如果想要到达符合要求的效果,只需在一次调用 plt.boxplot() 中,同时绘制多个箱形图即可,如下所示:

data = np.random.randn(200, 6)
#绘制图形
plt.boxplot(data)
# 添加标题和标签
plt.title('Box Plot Example')
plt.ylabel('Value')
# 显示箱线图
plt.show()

1.2 3D图形绘制

导入:

from mpl_toolkits.mplot3d import Axes3D

1.2.1 3D散点图

3D  散点图的绘制方式与  2D  散点图基本相同,示例如下:

a, b, c = 10., 28., 8. / 3.
def lorenz_map(x, dt = 1e-2):
x_dt = np.array([a * (x[1] - x[0]), x[0] * (b - x[2]) - x[1], x[0] * x[1] - c * x[2]])
return x + dt * x_dt
points = np.zeros((2000, 3))
x = np.array([.1, .0, .0])
for i in range(points.shape[0]):
points[i], x = x, lorenz_map(x)
# Plotting
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')  # 使用add_subplot()方法创建三维坐标轴
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('Lorenz Attractor a=%0.2f b=%0.2f c=%0.2f' % (a, b, c))
ax.scatter(points[:, 0], points[:, 1],points[:, 2], zdir = 'z', c = 'c')
plt.show()

在Matplotlib中, scatter() 方法用于在三维坐标轴上绘制散点图。它可以将一系列的数据点以散点的形式表示在三维空间中。

scatter() 方法的语法如下:

scatter(x, y, z, c=None, s=None, marker=None, cmap=None, **kwargs)

其中,参数的意义如下:

scatter() 方法可以在一个三维坐标轴对象上调用,通过 ax.scatter() 的形式来绘制三维散点图。在调用 scatter() 时,将数据传递给 x y z 参数,然后可以使用 c s 参数来指定颜色和大小, marker 参数来指定标记类型, cmap 参数来指定颜色映射等。

绘制3D图形的步骤:

1、首先需要导入  Matplotlib  的三维扩展  Axes3D

from mpl_toolkits.mplot3d import Axes3D

2、对于三维绘图,需要创建一个  Figure  实例并附加一个  Axes3D  实例:

fig = plt.figure()
ax = fig.gca(projection='3d')

gca方法已经不能使用了,可以使用add_subplot方法:

ax = fig.add_subplot(111, projection='3d')  # 使用add_subplot()方法创建三维坐标轴

3、然后带入相应的方法即可,这里带入了scatter绘制散点图:

ax.scatter(points[:, 0], points[:, 1],points[:, 2], zdir = 'z', c = 'c')

1.2.2 3D曲线图

与在  3D  空间中绘制散点图类似,绘制  3D  曲线图同样需要设置一个  Axes3D  实例,然后调用其  plot()  方法:

a, b, c = 10., 28., 8. / 3.
def lorenz_map(x, dt = 1e-2):
x_dt = np.array([a * (x[1] - x[0]), x[0] * (b - x[2]) - x[1], x[0] * x[1] - c * x[2]])
return x + dt * x_dt
points = np.zeros((8000, 3))
x = np.array([.1, .0, .0])
for i in range(points.shape[0]):
points[i], x = x, lorenz_map(x)
# Plotting
fig = plt.figure()
ax = fig.add_subplot(projection = '3d')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title('Lorenz Attractor a=%0.2f b=%0.2f c=%0.2f' % (a, b, c))
ax.plot(points[:, 0], points[:, 1], points[:, 2], c = 'c')
plt.show()

1.2.3 3D标量场

3D  绘图方式类似与相应的  2D  绘图方式,但也有许多特有的三维绘图功能,例如将二维标量场绘制为  3D  曲面, plot_surface()  方法使用 x、 y和 z 三个序列将标量场显示为三维曲面(展示一个二维量在三维中的形状):

x = np.linspace(-3, 3, 256)
y = np.linspace(-3, 3, 256)
x_grid, y_grid = np.meshgrid(x, y) #使用`np.meshgrid()`方法将一维数组`x`和`y`转换为二维数组,得到`x_grid`和`y_grid`,用于表示XY平面上的点坐标网格。
print(x_grid)
z = np.sinc(np.sqrt(x_grid ** 2 + y_grid ** 2))
fig = plt.figure()
ax = fig.add_subplot(projection = '3d') #创建一个三维坐标轴对象。
ax.plot_surface(x_grid, y_grid, z, cmap=cm.viridis) #x_grid和y_grid表示XY平面上的点坐标网格,z表示每个点上的函数值。cmap=cm.viridis指定使用'viridis'颜色映射,用于在三维图上表示高度的颜色。
plt.show()

plot_surface() 的用法如下:

pythonCopy code
plot_surface(X, Y, Z, cmap=None, rstride=1, cstride=1, alpha=1.0, antialiased=False, **kwargs)

其中,参数的意义如下:

X Y Z 分别代表了数据在三维空间中的网格坐标和高度,而 cmap 参数可以用来调整表面的颜色。 rstride cstride 参数用于控制在Z方向和XY平面上的采样步长,可以用于优化绘制速度和图像精细度。 alpha 参数控制表面的透明度, antialiased 参数用于指定是否使用抗锯齿。

如果不希望看到三维曲面上显示的曲线色彩,可以使用  plot_surface()  的附加可选参数:

ax.plot_surface(x_grid, y_grid, z, cmap=cm.viridis, linewidth=0, antialiased=False)

示例:

x = np.linspace(-3, 3, 256)
y = np.linspace(-3, 3, 256)
x_grid, y_grid = np.meshgrid(x, y) #使用`np.meshgrid()`方法将一维数组`x`和`y`转换为二维数组,得到`x_grid`和`y_grid`,用于表示XY平面上的点坐标网格。
z = np.sinc(np.sqrt(x_grid ** 2 + y_grid ** 2))
fig = plt.figure()
ax = fig.add_subplot(projection = '3d') #创建一个三维坐标轴对象。
ax.plot_surface(x_grid, y_grid, z, cmap=cm.viridis, linewidth=0, antialiased=False) #x_grid和y_grid表示XY平面上的点坐标网格,z表示每个点上的函数值。cmap=cm.viridis指定使用'viridis'颜色映射,用于在三维图上表示高度的颜色。
plt.show()

可以仅保持曲线色彩,而曲面不使用其他颜色,这也可以通过  plot_surface()  的可选参数来完成:

x = np.linspace(-3, 3, 256)
y = np.linspace(-3, 3, 256)
x_grid, y_grid = np.meshgrid(x, y) #使用`np.meshgrid()`方法将一维数组`x`和`y`转换为二维数组,得到`x_grid`和`y_grid`,用于表示XY平面上的点坐标网格。
z = np.sinc(np.sqrt(x_grid ** 2 + y_grid ** 2))
fig = plt.figure()
ax = fig.add_subplot(projection = '3d') #创建一个三维坐标轴对象。
ax.plot_surface(x_grid, y_grid, z, edgecolor='b',color='w') #x_grid和y_grid表示XY平面上的点坐标网格,z表示每个点上的函数值。cmap=cm.viridis指定使用'viridis'颜色映射,用于在三维图上表示高度的颜色。
plt.show()

如果希望消除曲面,而仅使用线框进行绘制,可以使用  plot_wireframe()  函数, plot_wireframe()  参数与  plot_surface()  相同,使用两个可选参数  rstride  和  cstride  用于令  Matplotlib  跳过 x 和 y轴上指定数量的坐标,用于减少曲线的密度:

ax.plot_wireframe(x_grid, y_grid, z, cstride=10, rstride=10,color='c')

示例:

plot_wireframe() 的用法如下:

plot_wireframe(X, Y, Z, rstride=1, cstride=1, color=None, linewidth=1, antialiased=False, **kwargs)

其中,参数的意义如下:

X Y Z 分别代表了数据在三维空间中的网格坐标和高度, rstride cstride 参数用于控制在Z方向和XY平面上的采样步长,可以用于优化绘制速度和图像精细度。 color 参数用于指定线框的颜色, linewidth 参数用于调整线框的宽度, antialiased 参数用于指定是否使用抗锯齿。

1.2.4 绘制3D曲面

Matplotlib  也能够使用更通用的方式绘制三维曲面:

angle = np.linspace(0, 2 * np.pi, 32)
theta, phi = np.meshgrid(angle, angle)
r, r_w = .25, 1.
x = (r_w + r * np.cos(phi)) * np.cos(theta)
y = (r_w + r * np.cos(phi)) * np.sin(theta)
z = r * np.sin(phi)
# Display the mesh
fig = plt.figure()
ax = fig.add_subplot(projection = '3d')
ax.set_xlim3d(-1, 1)
ax.set_ylim3d(-1, 1)
ax.set_zlim3d(-1, 1)
ax.plot_surface(x, y, z, color = 'c', edgecolor='m', rstride = 2, cstride = 2)
plt.show()

同样可以使用  plot_wireframe()  替换对  plot_surface()  的调用,以便获得圆环的线框视图:

angle = np.linspace(0, 2 * np.pi, 32)
theta, phi = np.meshgrid(angle, angle)
r, r_w = .25, 1.
x = (r_w + r * np.cos(phi)) * np.cos(theta)
y = (r_w + r * np.cos(phi)) * np.sin(theta)
z = r * np.sin(phi)
# Display the mesh
fig = plt.figure()
ax = fig.add_subplot(projection = '3d')
ax.set_xlim3d(-1, 1)
ax.set_ylim3d(-1, 1)
ax.set_zlim3d(-1, 1)
ax.plot_wireframe(x, y, z, edgecolor='c', rstride = 2, cstride = 1)
plt.show()

1.2.5 在3D坐标中绘制2D图形

Axes3D  实例同样支持常用的二维渲染命令,如  plot()

ax.plot(x, u, zs=3, zdir='y', lw = 2, color = 'm')

这段代码使用 ax.plot() 方法在三维坐标轴中绘制一条线。

Axes3D 实例对  plot()  的调用有两个新的可选参数:  zdir  :用于决定在哪个平面上绘制2D绘图,可选值包括  x y  或  z ;  zs  :用于决定平面的偏移。 因此,要将二维图形嵌入到三维图形中,只需将二维原语用于  Axes3D  实例,同时使用可选参数, zdir  和  zs ,来放置所需渲染图形平面。

示例:

x = np.linspace(-3, 3, 256)
y = np.linspace(-3, 3, 256)
x_grid, y_grid = np.meshgrid(x, y)
z = np.exp(-(x_grid ** 2 + y_grid ** 2))
u = np.exp(-(x ** 2))
fig = plt.figure()
ax = fig.add_subplot(projection = '3d')
ax.set_zlim3d(0, 3)#ax.set_zlim3d()是Matplotlib中用于设置三维坐标轴的Z轴范围(限制)的方法。它用于限定Z轴的取值范围,从而控制绘图中Z轴显示的范围。set_zlim3d(zmin, zmax)
ax.plot(x, u, zs=3, zdir='y', lw = 2, color = 'm')
ax.plot(x, u, zs=-3, zdir='x', lw = 2., color = 'c')
ax.plot_surface(x_grid, y_grid, z, color = 'b')
plt.show()

除此之外,可以在 3D  空间中堆叠  2D  条形图:

alpha = 1. / np.linspace(1, 8, 5)
t = np.linspace(0, 5, 16)
t_grid, a_grid = np.meshgrid(t, alpha)
data = np.exp(-t_grid * a_grid)
# Plotting
fig = plt.figure()
ax = fig.add_subplot(projection = '3d')
cmap = cm.ScalarMappable(col.Normalize(0, len(alpha)), cm.viridis)  #颜色映射
for i, row in enumerate(data):
ax.bar(4 * t, row, zs=i, zdir='y', alpha=0.8, color=cmap.to_rgba(i))
plt.show()

1.2.6 3D柱形图

3D  柱体以网格布局定位, bar3d()  方法接受六个必需参数作为输入, bar3d() 是Matplotlib中用于绘制三维条形图的方法。它可以在三维坐标轴中绘制一个或多个条形,用于可视化三维数据。

bar3d() 的用法如下:

bar3d(x, y, z, dx, dy, dz, color='b', zsort='average', *args, **kwargs)

其中,参数的含义如下:

通过传递 x y z 的数据,以及 dx dy dz 的宽度和高度数据,你可以使用 bar3d() 方法绘制一个或多个三维条形。每个条形的中心点由 x y z 指定,宽度由 dx dy 指定,高度由 dz 指定。

color 参数用于设置条形的颜色,可以传递颜色字符串,如'red'、'blue'、'green'等,也可以使用缩写颜色字符串,如'r'、'b'、'g'等,或者使用颜色序列。

zsort 参数用于控制条形的绘制顺序,可以按照Z轴坐标的平均值、最小值或最大值对条形进行排序,或者不排序。

示例:

alpha = np.linspace(1, 8, 5)
t = np.linspace(0, 5, 16)
t_grid, a_grid = np.meshgrid(t, alpha)
data = np.exp(-t_grid * (1. / a_grid))
# Plotting
fig = plt.figure()
ax = fig.add_subplot(projection = '3d')
xi = t_grid.flatten()
yi = a_grid.flatten()
zi = np.zeros(data.size)
dx = .30 * np.ones(data.size)
dy = .30 * np.ones(data.size)
dz = data.flatten()
ax.set_xlabel('T')
ax.set_ylabel('Alpha')
ax.bar3d(xi, yi, zi, dx, dy, dz, color = 'c')
plt.show()

二、matplotlib绘图的风格和样式

2.1 matplotlib风格

为了满足不同的应用需求, Matplotlib  中包含了  28  种不同的风格,在进行绘图时,可以根据需要选择不同的绘图风格。使用以下代码可以获取  Matplotlib  中所有可用的风格:

import matplotlib as mpl
from matplotlib import pyplot as plt
# 查看 Matplotlib 可用绘图风格
print(plt.style.available

使用  plt.style.use("style")  可以修改默认的绘图风格,其中  style  为  Matplolib  中可用的风格:

# 设置默认绘图风格为 seaborn-darkgrid
plt.style.use("seaborn-darkgrid")
x = np.linspace(0, 2 * np.pi, 100)
y = np.cos(x)
plt.plot(x, y)
plt.show()

除此之外, Maplotlib  中还有一些非常有意思的风格,例如手绘风格:

# 启用手绘风格
plt.xkcd()
x = np.linspace(0, 2 * np.pi, 100)
y = np.cos(x)
plt.plot(x, y)
plt.show()

同样还有手绘风格的条形图:

#启用手绘风格
plt.xkcd()
data = [[10., 20., 30., 20.],[40., 25., 53., 18.],[6., 22., 52., 19.]]
x = np.arange(4)
plt.bar(x + 0.00, data[0], color = 'b', width = 0.25)
plt.bar(x + 0.25, data[1], color = 'g', width = 0.25)
plt.bar(x + 0.50, data[2], color = 'r', width = 0.25)
plt.show()

2.2 自定义颜色

2.2.1 自定义颜色

Matplotlib  中有多种定义颜色的方法,常见的方法包括:

4、HTML颜色字符串:Matplotlib可以将HTML颜色字符串解释为实际颜色。这些字符串被定义为#RRGGBB,其中RR、GG和BB` 分别是使用十六进制编码的红色、绿色和蓝色分量。

5、灰度字符串: Matplotlib  将浮点值的字符串表示形式解释为灰度,例如  0.75  表示中浅灰色。

2.2.2 使用自定义颜色绘制曲线

通过设置  plt.plot()  函数的参数  color  (或等效的简写为  c ),可以设置曲线的颜色,示例:

def pdf(x, mu, sigma):
a = 1. / (sigma * np.sqrt(2. * np.pi))
b = -1. / (2. * sigma ** 2)
return a * np.exp(b * (x - mu) ** 2)
x = np.linspace(-6, 6, 1000)
for i in range(5):
samples = np.random.standard_normal(50)
mu, sigma = np.mean(samples), np.std(samples)
plt.plot(x, pdf(x, mu, sigma), color = str(.15*(i+1)))
plt.plot(x, pdf(x, 0., 1.), color = 'k')
plt.plot(x, pdf(x, 0.2, 1.), color = '#00ff00')
plt.plot(x, pdf(x, 0.4, 1.), color = (0.9,0.9,0.0))
plt.plot(x, pdf(x, 0.4, 1.), color = (0.9,0.9,0.0,0.8))
plt.show()

2.2.3 使用自定义颜色绘制散点图

可以以同样的方式像控制曲线图一样控制散点图的颜色,有两种可用的形式:

2.2.3.1 给所有点使用相同的颜色

用从二元高斯分布中提取的两组点  y_1  和  y_2 ,每一组中点的颜色相同:

y_1 = np.random.standard_normal((150, 2)) #标准正太分布
y_1 += np.array((-1, -1)) # Center the distrib. at <-1, -1>
y_2 = np.random.standard_normal((150, 2))
y_2 += np.array((1, 1)) # Center the distrib. at <1, 1>
plt.scatter(y_1[:,0], y_1[:,1], color = 'c')
plt.scatter(y_2[:,0], y_2[:,1], color = 'b')
plt.show()

2.2.3.2 给每个点不同的颜色

需要为不同类别的点使用不同的颜色进行绘制,以观察不同类别间的差异情况。以Fisher’s iris数据集为例,其数据集中数据类似如下所示:

5.0,3.3,1.4,0.2,Iris-setosa
7.0,3.2,4.7,1.4,Iris-versicolor
4.0,5.2,9.5,9.3,Iris-virginica

数据集的每个点都存储在以逗号分隔的列表中。最后一列给出每个点的标签(标签包含三类: Iris-virginica Iris-versicolor  和  Iris-Vertosa )。在示例中,这些点的颜色将取决于它们的标签,如下所示:

label_set = (
b'Iris-setosa',
b'Iris-versicolor',
b'Iris-virginica',
)
def read_label(label):
return label_set.index(label)
data = np.loadtxt('data.data', delimiter = ',', converters = { 4 : read_label })
color_set = ('c', 'y', 'm')
color_list = [color_set[int(label)] for label in data[:,4]]
plt.scatter(data[:,0], data[:,1], color = color_list)
plt.show()

对于三种可能的标签,我们分别指定一种唯一的颜色,颜色在  color_set  中定义,标签在  label_set  中定义。 label_set  中的第  i  个标签与  color_set  中的第  i  个颜色相关联。然后我们利用它们把标签列表转换成颜色列表  color_list 。然后只需调用  plt.scatter()  一次即可显示所有点及其颜色。

2.2.4 给散点图的边使用自定义颜色

与  color  参数控制点的颜色一样,可以使用  edgecolor  参数控制数据点的边的颜色,可以为每个点的边设置相同的颜色:

data = np.random.standard_normal((100, 2))
plt.scatter(data[:,0], data[:,1], color = '1.0', edgecolor='r')
plt.show()

除了为每个点的边设置相同的颜色外,也可以像在为每个点定义不同的颜色部分中介绍的一样为每个点的边设置不边的颜色。

2.2.5 使用自定义颜色绘制条形图

控制绘制条形图使用的颜色与曲线图和散点图的工作原理相同,即通过可选参数  color

w_pop = np.array([5., 30., 45., 22.])
m_pop = np.array( [5., 25., 50., 20.])
x = np.arange(4)
plt.barh(x, w_pop, color='m')
plt.barh(x, -m_pop, color='c')
plt.show()

同样,使用  plt.bar()  和  plt.barh()  函数自定义颜色绘制条形图的工作方式与  plt.scatter()  完全相同,只需设置可选参数  color ,同时也可以参数  edgecolor  控制条形边的颜色。`

示例:

values = np.random.randint(100, size = 50)
color_set = ('c', 'm', 'y', 'b')
color_list = [color_set[(len(color_set) * val) // 100] for val in values]
plt.bar(np.arange(len(values)), values, color = color_list)
plt.show()

2.2.6 使用自定义颜色绘制饼图

自定义饼图颜色的方法类似于条形图:

color_set = ('c', 'm', 'y', 'b')
values = np.random.rand(6)
plt.pie(values, colors = color_set)
plt.show()

饼图接受使用  colors  参数(注意,此处是  colors ,而不是在  plt.plot()  中使用的  color  )的颜色列表。但是,如果颜色数少于输入值列表中的元素数,那么  plt.pie()  将循环使用颜色列表中的颜色。在示例中,使用包含四种颜色的列表,为了给包含六个值的饼图着色,其中有两个颜色将使用两次。

2.2.7 使用自定义颜色绘制箱型图

values = np.random.randn(100)
b = plt.boxplot(values)
for name, line_list in b.items():
for line in line_list:
line.set_color('m')
plt.show()

2.2.8 使用色彩映射绘制散点图

如果要在图形中使用多种颜色,逐个定义每种颜色并不是最佳方案,色彩映射可以解决此问题。色彩映射用一个变量对应一个值(颜色)的连续函数定义颜色。 Matplotlib  提供了几种常见的颜色映射;大多数是连续的颜色渐变。色彩映射在  matplotib.cm  模块中定义,提供创建和使用色彩映射的函数,它还提供了预定义的色彩映射选择。 函数  plt.scatter()  接受  color  参数的值列表,当提供  cmap  参数值时,这些值将被解释为色彩映射的索引:

n = 256
angle = np.linspace(0, 8 * 2 * np.pi, n)
radius = np.linspace(.5, 1., n)
x = radius * np.cos(angle)
y = radius * np.sin(angle)
plt.scatter(x, y, c = angle, cmap = cm.hsv)
plt.show()

2.2.9 使用色彩映射绘制条形图

plt.scatter()  函数内置了对色彩映射的支持,其他一些绘图函数也内置支持色彩映射。但是,有些函数(如  plt.bar()  )并未内置对色彩映射的支持,在这种情况下, Matplotlib  可以从颜色映射显式生成颜色:

使用matplotlb的color模块:

values = np.random.randint(99, size = 50)
cmap = cm.ScalarMappable(col.Normalize(0, 99), cm.binary)
plt.bar(np.arange(len(values)), values, color = cmap.to_rgba(values))
plt.show()

首先创建色彩映射  cmap ,以便将  [0, 99]  范围内的值映射到  matplotlib.cm.binary  的颜色。然后,函数  cmap.to_rgba  将值列表转换为颜色列表。因此,尽管  plt.bar()  并未内置色彩映射支持,但依旧可以使用并不复杂的代码实现色彩映射。

2.2.10 创建自定义配色方案

Matplotlib  使用的默认颜色考虑的主要对象是打印文档或出版物。因此,默认情况下,背景为白色,而标签、轴和其他注释则显示为黑色,在某些不同的使用环境中,我们可能需要使用的配色方案;例如,将图形背景设置为黑色,注释设置为白色。 在  Matplotlib  中,各种对象(如轴、图形和标签)都可以单独修改,但逐个更改这些对象的颜色配置并非最佳方案。我们可以使用在《Matplotlib安装与配置》介绍的方法,通过修改配置集中改变所有对象,以配置其默认颜色或样式:

mpl.rc('lines', linewidth = 2.)
mpl.rc('axes', facecolor = 'k', edgecolor = 'w')
mpl.rc('xtick', color = 'w')
mpl.rc('ytick', color = 'w')
mpl.rc('text', color = 'w')
mpl.rc('figure', facecolor = 'k', edgecolor ='w')
mpl.rc('axes', prop_cycle = mpl.cycler(color=[(0.1, .5, .75),(0.5, .5, .75)]))
x = np.linspace(0, 7, 1024)
plt.plot(x, np.sin(x))
plt.plot(x, np.cos(x))
plt.show()

2.3 自定义样式

2.3.1 自定义线条样式和线宽

在实践中,除了颜色,大多数情况下我们还要对图形的线条样式等进行控制,以为线条样式添加多样性。

2.3.1.2 自定义线条样式

linestyle 参数是Matplotlib中用于指定线条样式的可选参数。它用于控制在绘制折线图、曲线图等线性图时,线条的外观样式。

linestyle 参数的常用取值如下:

示例:

def gaussian(x, mu, sigma):
a = 1. / (sigma * np.sqrt(2. * np.pi))
b = -1. / (2. * sigma ** 2)
return a * np.exp(b * (x - mu) ** 2)
x = np.linspace(-6, 6, 1024)
plt.plot(x, gaussian(x, 0., 1.), color = 'y', linestyle = 'solid')
plt.plot(x, gaussian(x, 0., .5), color = 'c', linestyle = 'dashed')
plt.plot(x, gaussian(x, 0., .25), color = 'm', linestyle = 'dashdot')
plt.show()

使用  plt.plot()  的  linestyle  参数来控制曲线的样式,其他可用线条样式包括: solid dashed dotted dashdot 。同样,线条样式设置不仅限于  plt.plot() ,任何由线条构成的图形都可以使用此参数,也可以说  linestyle  参数可用于所有涉及线条渲染的命令。例如,可以修改条形图的线条样式:

n = 10
a = np.random.random(n)
b = np.random.random(n)
x = np.arange(n)
plt.bar(x, a, color='c')
plt.bar(x, a+b, bottom=a, color='w', edgecolor='black', linestyle = 'dashed')
plt.show()

可以通过 edgecolor  参数改变边线的默认颜色

2.3.1.2 自定义线宽

使用  linewidth  参数可以修改线条的粗细。默认情况下, linewidth  设置为1个单位。利用线条的粗细可以在视觉上强调某条特定的曲线。

示例:

def gaussian(x, mu, sigma):
a = 1. / (sigma * np.sqrt(2. * np.pi))
b = -1. / (2. * sigma ** 2)
return a * np.exp(b * (x - mu) ** 2)
x = np.linspace(-6, 6, 1024)
for i in range(64):
samples = np.random.standard_normal(50)
mu, sigma = np.mean(samples), np.std(samples) #平均值和标准差
plt.plot(x, gaussian(x, mu, sigma), color = '.75', linewidth = .5)
plt.plot(x, gaussian(x, 0., 1.), color = 'c', linewidth = 3.)
plt.show()

2.3.2 控制填充样式

Matplotlib  提供了填充图案用于填充平面。这些填充图案,对于仅包含黑白两色的图形中具有重要作用。

示例:

n = 10
a = np.random.random(n)
b = np.random.random(n)
x = np.arange(n)
plt.bar(x, a, color='w', hatch='x', edgecolor='black')
plt.bar(x, a+b, bottom=a, color='w', edgecolor='black', hatch='/')
plt.show()

具有填充呈现性的函数(如  plt.bar()  )都可以使用可选参数  hatch  控制填充样式,此参数的可选值包括: / ,  \ ,  | ,  - ,  + ,  x ,  o ,  O .  和  * ,每个值对应于不同的填充图案; edgecolor  参数可用于控制填充图案的颜色。

2.3.3 控制标记

2.3.3.1 控制标记样式

《Matplotlib图形绘制》中,我们已经了解了如何绘制曲线,并明白了曲线是由点之间的连线构成的;此外,散点图表示数据集中的每个点。而  Matplotlib  提供了多种形状,可以用其他类型的标记替换点的样式。 标记的指定方式包括以下几种:

a = np.random.standard_normal((100, 2))
a += np.array((-1, -1))
b = np.random.standard_normal((100, 2))
b += np.array((1, 1))
plt.scatter(a[:,0], a[:,1], color = 'm', marker = 'x')
plt.scatter(b[:,0], b[:,1], color = 'c', marker = '^')
plt.show()

使用  marker  参数,可以为每个数据集合指定不同的标记。

如果我们需要为每个点定义不同样式该怎么办呢?与  color  参数不同, marker  参数不接受标记样式列表作为输入。因此,我们不能实现  plt.scatter()  的单次调来显示具有不同标记的多个点集。解决方案是,将每种类型的数据点分隔置不同集合中,并为每个集合单独调用  plt.scatter()  调用:

label_list = (
b'Iris-setosa',
b'Iris-versicolor',
b'Iris-virginica',
)
colors = ['c','y','m']
def read_label(label):
return label_list.index(label)
data = np.loadtxt('data.data', delimiter = ',', converters = { 4 : read_label })
marker_set = ('^', 'x', '.')
for i, marker in enumerate(marker_set):
data_subset = np.asarray([x for x in data if x[4] == i])
plt.scatter(data_subset[:,0], data_subset[:,1], color = colors[i], marker = marker)
plt.show()

对于  plt.plot() ,也可以使用相同的标记参数访问标记样式。当数据点密集时,每个点都使用标记进行显示将会导致图片混乱,因此  Matplotlib  提供了  markevery  参数,允许每隔  N  个点显示一个标记:

示例:

x = np.linspace(-6, 6, 1024)
y_1 = np.sinc(x)
y_2 = np.sinc(x) + 1
plt.plot(x, y_1, marker = 'x', color = '.75',label = 'y-1')
plt.plot(x, y_2, marker = 'o', color = 'k', markevery = 64,label = 'y-2')
plt.legend()
plt.show()

2.3.3.2 控制标记的大小

标记的大小可选参数  s  进行控制:

示例:

a = np.random.standard_normal((100, 2))
a += np.array((-1, -1))
b = np.random.standard_normal((100, 2))
b += np.array((1, 1))
plt.scatter(a[:,0], a[:,1], c = 'm', s = 100.)
plt.scatter(b[:,0], b[:,1], c = 'c', s = 25.)
plt.show()

标记的大小由  plt.scatter()  的参数  s  设置,但应注意它设置的是标记的表面积倍率而非半径。 plt.scatter()  函数还可以接受列表作为  s  参数的输入,其表示每个点对应的大小。

示例:

m = np.random.standard_normal((1000, 2))
r_list = np.sum(m ** 2, axis = 1)
plt.scatter(m[:, 0], m[:, 1], c = 'w', edgecolor='c', marker = 'o', s = 32. * r_list)
plt.show()

对于Plot方法, plt.plot()  函数允许在  markersize  (或简写为  ms  )参数的帮助下更改标记的大小,但是此参数不接受列表作为输入。

2.3.3.3 自定义标记

虽然  Matplotlib  提供了多种标记形状。但是在某些情况下我们可能仍然找不到适合具体需求的形状。例如,我们可能希望使用公司徽标等作为形状。 在  Matplotlib  中,将形状描述为一条路径——一系列点的连接。因此,如果要定义我们自己的标记形状,必须提供一系列的点:

示例:

shape_description = [
( 1., 2., mpath.Path.MOVETO),
( 1., 1., mpath.Path.LINETO),
( 2., 1., mpath.Path.LINETO),
( 2., -1., mpath.Path.LINETO),
( 1., -1., mpath.Path.LINETO),
( 1., -2., mpath.Path.LINETO),
(-1., -2., mpath.Path.LINETO),
(-1., -1., mpath.Path.LINETO),
(-2., -1., mpath.Path.LINETO),
(-2., 1., mpath.Path.LINETO),
(-1., 1., mpath.Path.LINETO),
(-1., 2., mpath.Path.LINETO),
( 0., 0., mpath.Path.CLOSEPOLY),
]
#mpath.Path.MOVETO表示将移动到指定点,mpath.Path.LINETO表示在指定点之间绘制一条直线,mpath.Path.CLOSEPOLY表示绘制一个闭合路径。
u, v, codes = zip(*shape_description)
#这行代码使用zip()函数和解包操作将shape_description列表中的元组拆分成三个分别包含x坐标、y坐标和代码的元组。
my_marker = mpath.Path(np.asarray((u, v)).T, codes)
#这是使用mpath.Path()方法创建自定义的路径对象my_marker。这个路径由x坐标数组u和y坐标数组v组成,并使用对应的代码数组codes来指定路径上的点和连接方式。
data = np.random.rand(8, 8)
plt.scatter(data[:,0], data[:, 1], c = 'm', marker = my_marker, s = 75)
plt.show()

Path  对象的构造函数将坐标列表和指令列表作为输入;每个坐标一条指令,使用一个列表将坐标和指令融合在一起,然后将坐标列表和指令传递给路径构造函数.

形状是通过光标的移动来描述的:

理论上,任何形状都是可能的。

总结

到此这篇关于python matplotlib绘图详解的文章就介绍到这了,更多相关python matplotlib绘图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文