python——matplotlib绘图详解大全

目录


一、图形绘制大全

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: 一维数组或列表,表示数据点在X轴上的位置。

  • y: 一维数组或列表,表示数据点在Y轴上的位置。

  • linestyle: (可选参数) 字符串,表示线条的样式。默认值为None,表示使用默认的线条样式。你可以指定不同的线条样式,如实线(‘-‘)、虚线(‘–‘)、点划线(‘-.’)、点线(‘:’)等。

  • marker: (可选参数) 字符串,表示数据点的标记类型。默认值为None,表示不显示数据点的标记。你可以指定不同的标记类型,如圆圈(‘o’)、方块(‘s’)、三角形(‘^’)等。

  • color: (可选参数) 字符串,表示线条和标记的颜色。默认值为None,表示使用默认的颜色。你可以使用颜色字符串,如’red’、’blue’、’green’等,也可以使用缩写颜色字符串,如’r’、’b’、’g’等。

  • label: (可选参数) 字符串,表示线条的标签。默认值为None。当你想为绘制的线条添加图例时,可以设置此标签。

  • **kwargs: (可选参数) 这是一些可选的关键字参数,用于配置线条的其他属性,比如线条宽度、透明度等。

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

绘制多条线时,可以多次调用plot()方法,每次传递不同的xy数据,并根据需要设置不同的样式和颜色。当绘制多条线时,你可以使用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 文件为例,其他诸如 ExcelCSV文件 等同样可以进行读取,并用于可视化绘制。

例如:

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)

参数解释:

  • x:横坐标数据,是一个数组或Series,用于表示散点图中每个点的横坐标位置。

  • y:纵坐标数据,是一个数组或Series,用于表示散点图中每个点的纵坐标位置。

  • s:点的大小,可以是一个数值或数组,控制散点的大小。默认值为 None,表示使用默认点大小。

  • c:点的颜色,可以是一个颜色字符串、颜色列表或数组,用于控制散点的颜色。默认值为 None,表示使用默认颜色。

  • marker:点的标记样式,可以是一个标记字符串,例如 ‘o’ 表示圆点,’s’ 表示方块等。默认值为 None,表示使用默认标记样式。

  • cmap:用于指定颜色映射的Colormap对象或字符串。它在指定c参数为数值时使用,将数值映射到颜色空间。默认值为 None,表示使用默认颜色映射。

  • norm:用于归一化数据的Normalize对象。它在指定c参数为数值时使用。默认值为 None,表示使用默认的归一化方式。

  • vminvmax:用于设置颜色映射范围的最小值和最大值。它们在指定c参数为数值时使用。默认值为 None,表示使用数据的最小值和最大值作为范围。

  • alpha:点的透明度,取值范围为 [0, 1],其中 0 表示完全透明,1 表示完全不透明。默认值为 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)

其中,参数的意义如下:

  • x: 这是一个可迭代对象,通常是一个列表或数组,用于指定条形图的横坐标位置。每个元素表示一个条形的横坐标位置。

  • height: 这是一个可迭代对象,通常是一个列表或数组,用于指定条形图的高度或长度。每个元素表示一个条形的高度。

  • width: (可选参数) 这是一个标量或一个可迭代对象,用于指定条形的宽度。默认值为0.8,表示每个条形的宽度为0.8个单位。如果想要自定义每个条形的宽度,可以传递一个标量值或一个与xheight长度相同的可迭代对象。

  • align: (可选参数) 这是一个字符串,用于指定条形的对齐方式。默认值是'center',表示条形在横坐标上居中对齐。其他可能的取值有'edge'表示条形以横坐标左边缘对齐,或'align'表示条形以横坐标右边缘对齐。

  • **kwargs: (可选参数) 这是一些可选的关键字参数,用于配置条形图的其他属性,比如颜色、标签、透明度等。例如,可以使用color参数来指定条形的颜色,label参数来为条形添加标签等。

一旦调用了plt.bar来绘制条形图,可以使用plt.xlabelplt.ylabelplt.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)

其中,参数的意义如下:

  • y: 这是一个可迭代对象,通常是一个列表或数组,用于指定条形图的纵坐标位置。每个元素表示一个条形的纵坐标位置。

  • width: 这是一个可迭代对象,通常是一个列表或数组,用于指定条形图的宽度或长度。每个元素表示一个条形的宽度。

  • height: (可选参数) 这是一个标量或一个可迭代对象,用于指定条形的高度。默认值为0.8,表示每个条形的高度为0.8个单位。如果想要自定义每个条形的高度,可以传递一个标量值或一个与ywidth长度相同的可迭代对象。

  • left: (可选参数) 这是一个标量或一个可迭代对象,用于指定条形的起始值。默认值为None,表示每个条形从0开始。如果要实现堆积效果,可以通过left参数指定每个条形的起始值。

  • **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)

其中,参数的意义如下:

  • x: 这是一个1维数组或列表,表示各个部分的数据值。这些数据值将用于计算各个部分所占的比例,并绘制饼图。

  • explode: (可选参数) 这是一个1维数组或列表,用于指定是否将某些部分从饼图中分离出来。默认值为None,表示不进行分离。如果要分离某些部分,可以传递一个与x长度相同的数组,其中数值大于0表示分离的距离。

  • labels: (可选参数) 这是一个1维数组或列表,用于指定饼图中每个部分的标签。默认值为None,表示不显示标签。如果要显示标签,可以传递一个与x长度相同的数组,其中包含各个部分的标签文本。

  • colors: (可选参数) 这是一个1维数组或列表,用于指定饼图中每个部分的颜色。默认值为None,表示使用默认的颜色循环。如果要自定义颜色,可以传递一个与x长度相同的数组,其中包含各个部分的颜色。

  • autopct: (可选参数) 这是一个字符串或函数,用于显示各个部分所占的百分比。默认值为None,表示不显示百分比。如果传递一个字符串,比如'%1.1f%%',将显示小数点后一位的百分比。如果传递一个函数,该函数将接收一个数值作为参数,并返回一个字符串用于显示百分比。

  • shadow: (可选参数) 这是一个布尔值,用于指定是否在饼图下方添加阴影。默认值为False,表示不添加阴影。

  • startangle: (可选参数) 这是一个标量,用于指定饼图的起始角度。默认值为0,表示从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)

其中,参数的意义如下:

  • x: 这是一个1维数组或列表,表示要绘制直方图的数据。

  • bins: (可选参数) 这是一个整数或指定分 bin 的数组,用于控制直方图的箱子(bin)数量和位置。默认值为None,表示使用自动选择的箱子数量。可以传递一个整数值来指定箱子数量,或者传递一个数组来指定具体的箱子边界。

  • range: (可选参数) 这是一个元组或列表,用于指定直方图的数据范围。默认值为None,表示使用整个数据的范围。可以传递一个元组或列表,如(min_value, max_value),来限制直方图显示的数据范围。

  • density: (可选参数) 这是一个布尔值,用于指定是否对直方图进行标准化。默认值为False,表示直方图显示的是原始数据的频数。如果设置为True,直方图将显示相对频率,使得直方图的面积总和为1。

  • cumulative: (可选参数) 这是一个布尔值,用于指定是否绘制累积直方图。默认值为False,表示绘制原始直方图。如果设置为True,将绘制累积直方图,即显示每个箱子内数据的累积数量。

  • color: (可选参数) 这是一个字符串或颜色代码,用于指定直方图的填充颜色。

  • edgecolor: (可选参数) 这是一个字符串或颜色代码,用于指定直方图的边界线颜色。

  • **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)

其中,参数的意义如下:

  • data: 这是一个列表、数组或多个列表/数组的组合,表示要绘制箱线图的数据集。可以传递一个列表或数组,也可以传递多个列表或数组组成的组合,用于在同一个图中绘制多个箱线图。

  • notch: (可选参数) 这是一个布尔值,用于指定是否在箱线图中绘制缺口。默认值为None,表示不绘制缺口。如果设置为True,箱线图将带有缺口,有助于显示数据集的置信区间。

  • sym: (可选参数) 这是一个字符串,用于指定异常值的表示方式。默认值为None,表示使用’+’表示异常值。可以传递其他符号或空字符串来自定义异常值的表示。

  • vert: (可选参数) 这是一个布尔值,用于指定箱线图的方向。默认值为None,表示绘制垂直箱线图。如果设置为False,将绘制水平箱线图。

  • whis: (可选参数) 这是一个标量或元组,用于指定箱线图中须的长度。默认值为None,表示使用默认值1.5。可以传递一个标量值或一个元组(lower, upper),用于自定义须的长度。

  • positions: (可选参数) 这是一个标量或列表,用于指定箱线图的位置。默认值为None,表示每个数据集在x轴上均匀分布。可以传递一个标量值或一个与数据集数量相同的列表,用于自定义箱线图的位置。

  • widths: (可选参数) 这是一个标量或列表,用于指定箱线图的宽度。默认值为None,表示使用默认宽度。可以传递一个标量值或一个与数据集数量相同的列表,用于自定义箱线图的宽度。

  • patch_artist: (可选参数) 这是一个布尔值,用于指定是否对箱线图的盒体使用填充颜色。默认值为None,表示不使用填充颜色。如果设置为True,箱线图的盒体将被填充,可以通过boxprops参数指定填充颜色和其他属性。

  • **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()

 

  1. 图中黄线是分布的中位数。

  2. 方形箱框包括从下四分位数Q1到上四分位数Q3的50%的数据。

  3. 下盒须的下四分位延伸到1.5 (Q3-Q1)。

  4. 上盒须从上四分位延伸至1.5 (Q3-Q1)。

  5. 离盒须较远的数值用圆圈标记。

要在单个图形中绘制多个箱形图,对每个箱形图调用一次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)

其中,参数的意义如下:

  • x: 这是一个1维数组或列表,表示散点图在X轴上的位置。

  • y: 这是一个1维数组或列表,表示散点图在Y轴上的位置。

  • z: 这是一个1维数组或列表,表示散点图在Z轴上的位置,即垂直于XY平面的位置。

  • c: (可选参数) 这是一个1维数组或列表,用于指定每个散点的颜色。默认值为None,表示使用默认的颜色映射。你可以传递一个与xyz长度相同的数组,其中每个元素表示对应散点的颜色。

  • s: (可选参数) 这是一个标量或1维数组或列表,用于指定散点的大小。默认值为None,表示使用默认的点大小。如果传递一个标量值,所有散点的大小将相同。如果传递一个与xyz长度相同的数组,每个元素表示对应散点的大小。

  • marker: (可选参数) 这是一个字符串,用于指定散点的标记类型。默认值为None,表示使用圆圈标记。可以传递其他标记类型,如’s’, ‘o’, ‘^’等。

  • cmap: (可选参数) 这是一个Colormap对象或字符串,用于指定颜色映射。默认值为None,表示使用默认的颜色映射。你可以传递一个Colormap对象,或者使用字符串指定常见的颜色映射,如’viridis’、’plasma’、’jet’等。

  • zdirscatter()方法中的一个可选参数,用于指定在三维坐标轴上散点的投影方向。它用于控制散点在三维空间中的展示方式。

    scatter()方法中,zdir可以取三个值:’x’、’y’和’z’。这些值分别表示在X轴、Y轴和Z轴上展示散点的投影。

    zdir设置为’x’时,散点在XY平面上的投影将在X轴上展示。 当zdir设置为’y’时,散点在XZ平面上的投影将在Y轴上展示。 当zdir设置为’z’时,散点在XY平面上的投影将在Z轴上展示。

    默认情况下,zdir的值为None,此时散点将在XY平面上展示,而不会在X、Y或Z轴上产生投影。

  • **kwargs: (可选参数) 这是一些可选的关键字参数,用于配置散点图的其他属性,比如透明度、边缘颜色等。

scatter()方法可以在一个三维坐标轴对象上调用,通过ax.scatter()的形式来绘制三维散点图。在调用scatter()时,将数据传递给xyz参数,然后可以使用cs参数来指定颜色和大小,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: 二维数组,表示数据在X轴上的坐标。它的形状应该与Z的形状相同。

  • Y: 二维数组,表示数据在Y轴上的坐标。它的形状应该与Z的形状相同。

  • Z: 二维数组,表示数据在三维空间中的高度或数值。它的形状应该与XY的形状相同。

  • cmap: Colormap对象或字符串,用于指定颜色映射。默认值为None,表示使用默认的颜色映射。你可以传递一个Colormap对象,或者使用字符串指定常见的颜色映射,如’viridis’、’plasma’、’jet’等。

  • rstride: 整数,表示在Z方向上采样的步长。默认值为1,表示不进行采样。较大的值会导致更少的绘制点,从而加快绘制速度,但可能会影响图像的精细程度。

  • cstride: 整数,表示在XY平面上采样的步长。默认值为1,表示不进行采样。较大的值会导致更少的绘制点,从而加快绘制速度,但可能会影响图像的精细程度。

  • alpha: 浮点数,表示表面的透明度。默认值为1.0,表示不透明。取值范围为0.0到1.0,其中0.0表示完全透明,1.0表示完全不透明。

  • antialiased: 布尔值,表示是否使用抗锯齿。默认值为False,表示不使用抗锯齿。如果设置为True,图像会更加平滑,但可能会增加绘制时间。

  • 色。

    在绘制三维表面图时,表面由许多小的三角形或多边形组成,这些小形状之间的边缘线通常是默认颜色。通过设置edgecolor参数,你可以控制这些边缘线的颜色,使其与表面的颜色不同,从而增加图形的可视化效果。

    edgecolor可以接受一个颜色值的字符串或RGB元组。常用的颜色值字符串如下:

    • ‘b’:蓝色

    • ‘g’:绿色

    • ‘r’:红色

    • ‘c’:青色(蓝绿色)

    • ‘m’:洋红(品红色)

    • ‘y’:黄色

    • ‘k’:黑色

    • ‘w’:白色

    你也可以传递一个RGB元组,例如(0.1, 0.2, 0.3),表示RGB颜色分量的值在0到1之间。这样,你可以自定义边缘线的颜色。

  • **kwargs: 可选的关键字参数,用于配置表面图的其他属性,比如线条颜色、线条样式等。

XYZ分别代表了数据在三维空间中的网格坐标和高度,而cmap参数可以用来调整表面的颜色。rstridecstride参数用于控制在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() 相同,使用两个可选参数 rstridecstride 用于令 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: 二维数组,表示数据在X轴上的坐标。它的形状应该与Z的形状相同。

  • Y: 二维数组,表示数据在Y轴上的坐标。它的形状应该与Z的形状相同。

  • Z: 二维数组,表示数据在三维空间中的高度或数值。它的形状应该与XY的形状相同。

  • rstride: 整数,表示在Z方向上采样的步长。默认值为1,表示不进行采样。较大的值会导致更少的绘制点,从而加快绘制速度,但可能会影响图像的精细程度。

  • cstride: 整数,表示在XY平面上采样的步长。默认值为1,表示不进行采样。较大的值会导致更少的绘制点,从而加快绘制速度,但可能会影响图像的精细程度。

  • color: 颜色或颜色序列,用于指定线框的颜色。默认值为None,表示使用默认的颜色。

  • linewidth: 浮点数,表示线框的宽度。默认值为1。

  • antialiased: 布尔值,表示是否使用抗锯齿。默认值为False,表示不使用抗锯齿。如果设置为True,线框会更加平滑,但可能会增加绘制时间。

  • **kwargs: 可选的关键字参数,用于配置线框图的其他属性,比如线条样式等。

XYZ分别代表了数据在三维空间中的网格坐标和高度,rstridecstride参数用于控制在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()方法在三维坐标轴中绘制一条线。

  • x: 一维数组或列表,表示数据点在X轴上的位置。

  • u: 一维数组或列表,表示数据点在Y轴上的位置。

  • zs: 数字或一维数组,表示数据点在Z轴上的位置。在这个例子中,zs=3表示数据点在Z轴上的位置都是3,也就是说这条线的所有点都在Z=3这个平面上。如果传递一个一维数组,表示每个数据点在Z轴上的位置。

  • zdir: 字符串,表示投影方向。这个参数用于控制这条线在三维空间中的展示方向。在这个例子中,zdir='y'表示这条线在XY平面上的投影将在Y轴上展示。

  • lw: (可选参数) 数字,表示线条的宽度。默认值为2。

  • color: (可选参数) 字符串,表示线条的颜色。默认值为’m’,表示线条颜色为洋红色(品红色)。你可以使用颜色字符串,如’red’、’blue’、’green’等,也可以使用缩写颜色字符串,如’r’、’b’、’g’等。

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

示例:

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. col.Normalize(0, len(alpha)): 这是创建一个归一化(Normalize)对象的操作。colmatplotlib.colors模块的别名,用于访问颜色相关的功能。Normalize(0, len(alpha))表示将数据映射到0到len(alpha)之间的范围。这个操作通常用于将数据规范化到特定范围,以便后续的颜色映射。

  2. cm.viridis: 这是指定使用的颜色映射。cmmatplotlib.cm模块的别名,用于访问颜色映射功能。viridis是一种预定义的颜色映射,它包含一系列颜色,从低值(例如0)到高值(例如1)依次变化,用于在绘图中表示数据的高低或其他属性。

  3. cm.ScalarMappable(col.Normalize(0, len(alpha)), cm.viridis): 这个操作将前面创建的归一化对象和颜色映射对象组合在一起,生成一个可映射到颜色的标量映射对象。这个对象在绘图中用于将数值映射到对应的颜色.

  4. ax.bar(4 * t, row, zs=i, zdir='y', alpha=0.8, color=cmap.to_rgba(i)): 在三维坐标轴中绘制一个条形,4 * t表示条形的X坐标,row表示条形的高度,zs=i表示条形的Z坐标,zdir='y'表示条形在XY平面上的投影将在Y轴上展示,alpha=0.8表示条形的透明度为0.8,color=cmap.to_rgba(i)表示条形的颜色根据i通过颜色映射对象cmap获取

1.2.6 3D柱形图

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

bar3d()的用法如下:

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

其中,参数的含义如下:

  • x: 一维数组或列表,表示每个条形的中心点在X轴上的位置。

  • y: 一维数组或列表,表示每个条形的中心点在Y轴上的位置。

  • z: 一维数组或列表,表示每个条形的中心点在Z轴上的位置,即条形的高度。

  • dx: 一维数组或列表,表示每个条形在X轴方向上的宽度。

  • dy: 一维数组或列表,表示每个条形在Y轴方向上的宽度。

  • dz: 一维数组或列表,表示每个条形在Z轴方向上的高度,即条形的厚度。

  • color: (可选参数) 字符串或颜色序列,表示条形的颜色。默认值为蓝色(‘b’)。

  • zsort: (可选参数) 字符串,表示条形的绘制顺序。默认值为’average’,表示按照Z轴坐标的平均值对条形进行排序。也可以选择’min’表示按照Z轴坐标的最小值排序,’max’表示按照Z轴坐标的最大值排序,或者’none’表示不排序。

  • *args**kwargs: (可选参数) 这是一些额外的位置参数和关键字参数,用于配置条形的其他属性,比如线条颜色、线条样式等。

通过传递xyz的数据,以及dxdydz的宽度和高度数据,你可以使用bar3d()方法绘制一个或多个三维条形。每个条形的中心点由xyz指定,宽度由dxdy指定,高度由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") 可以修改默认的绘图风格,其中 styleMatplolib 中可用的风格:

# 设置默认绘图风格为 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 中有多种定义颜色的方法,常见的方法包括:

  1. 三元组 (Triplets):颜色可以描述为一个实数三元组,即颜色的红、蓝、绿分量,其中每个分量在 [0,1] 区间内。因此,(1.0, 0.0, 0.0) 表示纯红色,而 (1.0, 0.0, 1.0) 则表示粉色。

  2. 四元组 (Quadruplets):它们前三个元素与三元组定义相同,第四个元素定义透明度值。此值也在 [0,1] 区间内。将图形渲染到图片文件中时,使用透明颜色可以使绘制图形与背景进行混合。

  3. 预定义名称:Matplotlib 将标准 HTML 颜色名称解释为实际颜色。例如,字符串 red 即可表示为红色。同时一些某些颜色的具有简洁的别名,如下表所示:

  4.  

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

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 使用自定义颜色绘制散点图

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

  1. 为所有点使用相同的颜色 :所有点都将以相同的颜色显示。

  2. 为每个点定义不同的颜色:为每个点提供不同的颜色。

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

用从二元高斯分布中提取的两组点 y_1y_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-virginicaIris-versicolorIris-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参数的常用取值如下:

  • '-''solid': 实线 (默认值)

  • '--''dashed': 虚线

  • ':''dotted': 点线

  • '-.''dashdot': 点划线

示例:

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 参数来控制曲线的样式,其他可用线条样式包括:soliddasheddotteddashdot。同样,线条样式设置不仅限于 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 控制填充样式,此参数的可选值包括:/\|-+xoO.*,每个值对应于不同的填充图案;edgecolor 参数可用于控制填充图案的颜色。

2.3.3 控制标记

2.3.3.1 控制标记样式

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

  1. 预定义标记:预定义的形状,表示为 [0, 8] 范围内的整数或某些预定义的字符串。

  2. 顶点列表:值对列表,用作形状路径的坐标。

  3. 正多边形:表示 N 边正多边形的三元组 (N, 0, angle) ,其中 angle 为旋转角度。

  4. 星形多边形:它表示为三元组 (N, 1, angle),代表 N 边正星形,其中 angle 为旋转角度。

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

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

  • MOVETO:此指令将光标移动到指定的坐标,并不画线。

  • LINETO:这将在光标当前点和目标点之间绘制直线,并将光标移动至目标点。

  • CLOSEPOLY:此指令仅用于关闭路径,每个形状都以这条指示结束。

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

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
xiaoxingxing的头像xiaoxingxing管理团队
上一篇 2023年9月7日
下一篇 2023年9月7日

相关推荐