matplotlib基础--1

1) 画布

matploblib库是一个用于数据可视化和绘图的python库。它提供了大量的函数和类,可以帮助用户轻松地创建各种类型地图表,包括直方图,箱形图、散点图、饼图、条形图和密度图等。使用matplotlib的过程中,遇到的难点并不在于绘制各类的图形,因为每种图形都有其对应的API。难点在于对绘制的图形进行调整,这些调整包括:

  • 图形的大小
  • 多个图形的组合
  • 坐标轴的方向,可读和精度
  • 图形的颜色和字体

进行这些调整需要对matplotlib的绘图机制和其中的主要元素有个整体的了解。在此首先整体介绍matplotlib绘制的图形中的主要元素,然后重点介绍其中第一个重要的元素:画布。

1.1)  主要元素

下面绘制一个简单的图形来演示matplotlib绘图时主要的元素。

import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
%matplotlib inline

x=np.array(np.pi*2 * np.linspace(0,1,20))
y1=np.sin(x)
fig=plt.figure()
fig.set_size_inches(10,4)
fig.set_facecolor('yellow')
fig.suptitle('whole figure caption')
fig.subplots_adjust(wspace=0.3)

ax1=fig.add_subplot(1,2,1)
ax1.set_title("fig1 title")
ax1.set_xlabel("fig1 x-axis")
ax1.set_ylabel("fig1 y-axis")
ax1.plot(x,y1)

ax2=fig.add_subplot(1,2,2)
ax2.set_title("fig2 title")
ax2.set_xlabel("fig2 x-axis")
ax2.set_ylabel("fig2 y-axis")
ax2.plot(x,y1)
y2=np.cos(x)
ax2.plot(x,y2)
ax2.legend(['sin','cos'])

fig.show()

上例中,我们绘制了2个子图。

matplotlib基础--1_第1张图片

主要的元素包括,图形的大小,图形的标题(主标题和子图标题),坐标轴(轴标签和可读),图例,子图中曲线 (这里可以根据情况换成其它图形,比如柱状图,散点图等)。

上面的示例代码不用太关心,这里只是为了现实matplot的主要元素。后续将介绍各个组要元素的常用属性,最终的目的是能够灵活绘制符合显示要求的图形,而不仅仅只是绘制图形。

本节介绍的主要元素是画布。

2)画布

画布是其它所有的元素的载体,可以说是最重要,也是最容易被忽视的元素。绘制图形之前,第一件事即是创建画布。

2.1 主要属性

创建画布之后,一般主要用到的属性是调整画布的大小和颜色。

matplotlib画布的大小通过设置英寸和dpi来实现,dpi表示一英寸有多少像素。

2.1.1 画布大小

比如以下示例

import numpy as np
import matplotlib
# matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
%matplotlib inline

fig = plt.figure(figsize=[6,3],dpi=100)
fig.suptitle("caption")
x = np.linspace(0,1,20)
y = np.sin(x * 2 * np.pi)
plt.plot(x, y)
plt.show()

matplotlib基础--1_第2张图片

修改dpi=200,图形明显变大和清晰。

fig = plt.figure(figsize=[6,3],dpi=200)
 2.1.2 画布颜色

除了大小,设置画布的颜色也是比较常用的。

颜色主要有两种,背景色和边框颜色(默认的边框宽度是0,随意要设置边框颜色,同时设置边框的宽度)。

比如:下面示例设置了背景色为橙色,边框宽度为10,颜色为黄色。

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline

fig = plt.figure(figsize=[6,3],edgecolor="orange",linewidth=10,facecolor="yellow")
fig.suptitle("caption")
x = np.linspace(0,1,20)
y = np.sin(x * 2 * np.pi)
plt.plot(x, y)
plt.show()

matplotlib基础--1_第3张图片

2.2 主要方法

除了属性,画布还有几个方法也是经常使用的。

2.2.1 设置标题

上面的示例中已经包含了也就是suptitle()方法。

2.2.2 添加子图

添加子图用add_subplot()方法,这个方法的参数一般三个数字xyz,x表示有几行,y表示有几列,z表示是第一个子图。

比如,一行两列3个图。

import matplotlib.pyplot as plt
%matplotlib inline

fig = plt.figure()
fig.add_subplot(121)
fig.add_subplot(122)

matplotlib基础--1_第4张图片

两行一列2个图:

import matplotlib.pyplot as plt
%matplotlib inline

fig = plt.figure()
fig.add_subplot(211)
fig.add_subplot(212)

matplotlib基础--1_第5张图片

两个两列4个图:

import matplotlib.pyplot as plt
%matplotlib inline

fig = plt.figure()
fig.add_subplot(221)
fig.add_subplot(222)
fig.add_subplot(223)
fig.add_subplot(224)

matplotlib基础--1_第6张图片

2.2.3 保存图像

画布还有个重要的功能就是把显示的图像保存下来,即savefig()方法。

可以把绘制的图形保存到磁盘,用于分享或者制作报告。

fig.savefig("/home/user/pp.png")

3) 总结回顾

画布让我们可以整体上设置图形的质量和排版,分享和作图过程中虽然不用过多考虑它,但是最终如果要出报告和文档,画布的设置就变得重要了。

画布是绘图的第一步,接下来这个系列会逐步介绍matplotlib的其它主要元素。

2 子图

使用matplotlib对分析结果可视化时,比较各类分析结果是常见的场景。在这类场景之下,将多个分析结果绘制在一张图上,可以帮助用户方便地组合和分析多个数组集,提高数据可视化地效果和准确性。本节介绍matplotlib绘制子图地常用方法和技巧。

1)添加子图的方式

添加子图主要有两种方式:

一种是函数式风格(也就是上一节中画布中介绍的方式)

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

x = np.linspace(0,1,20)
y1 = np.cos(2 * np.pi * x)
y2 = np.sin(2 * np.pi * x)

fig= plt.figure(figsize=[6,4])
fig.add_subplot(211)
plt.plot(x,y1)

fig.add_subplot(212)
plt.plot(x,y2)

matplotlib基础--1_第7张图片

另一种风格是面向对象的风格(使用Axes对象)

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

x = np.linspace(0,1,20)
y1 = np.cos(2 * np.pi * x)
y2 = np.sin(2 * np.pi * x)

fig, ax = plt.subplots(1,2)

ax[0].plot(x,y1)
ax[1].plot(x,y2)

matplotlib基础--1_第8张图片 上面设置好子图之后,添加子图的顺序是从上到下,从左到右。

2 子图的布局

子图的布局是按照行列设置的,设置之后,相应的位置可以添加子图。

x = np.array(range(1,10))
rows, cols = 2,2
fig, ax = plt.subplots(rows, cols)

for i in range(rows):
    for j in range(cols):
        y = np.random.randint(1,100,9)
        ax[i,j].plot(x,y)

matplotlib基础--1_第9张图片

子图按照网格布局时,以上4个子图的Y轴刻度不一样,这样不利于比较。

x = np.array(range(1,10))
rows, cols = 2,2
fig, ax = plt.subplots(rows, cols,sharey='all')

for i in range(rows):
    for j in range(cols):
        y = np.random.randint(1,100,9)
        ax[i,j].plot(x,y)

matplotlib基础--1_第10张图片

 设置sharey='all'之后,Y轴刻度保持一致,这样比较曲线才有意义。上面的示例中X刻度是一致的,如果不一致,可以用sharex属性来设置。

3 复杂布局

3.1 不规则的网格

除了规则的网格布局,还可以通过GridSpec设置不规则的网格。

比如:

rows, cols = 3,3
grid = plt.GridSpec(rows, cols)

plt.subplot(grid[0,:2]) # 横向占两个单位0和1,竖直占1个单位0
plt.subplot(grid[0, 2]) # 横向占一个单位2,竖直占1个单位0

plt.subplot(grid[1,:2]) # 横向占一个单位0,竖直占1个单位1
plt.subplot(grid[1, 2]) # 横向占两个个单位1和2,竖直占1个单位1

plt.subplot(grid[2,:]) # 横向占三个单位0,1和2,竖直占1个单位2

matplotlib基础--1_第11张图片

上图设置了3行3列的网格,但是每个图形占用几个网格都是可以调整的。

3.2 嵌套图形

 除了网格,还可以通过相对定位的方式来绘制多个子图。

fig = plt.figure()

fig.add_axes([0.1,0.1,1, 1])
fig.add_axes([0.2,0.2,0.2, 0.2])
fig.add_axes([0.7,0.7,0.3, 0.15])

matplotlib基础--1_第12张图片

 上面按相对位置添加子图的函数add_axes的参数是一个4元列表。这个列表4个元素的含义:

  1. 第一个元素表示子图左下角距离画布左边的距离占总宽度的比例。
  2. 第二个元素表示子图左下角距离画布底边的距离占画布总高度的比例。
  3. 第三个元素表示子图占画布总宽度的比例。
  4. 第四个元素表示子图高度占画布总高度的比例。

注意:这里4个值都是比例。

4)总结回顾

matplotlib中每个子图可以有自己的标签,大小,位置和样式,可以方便地组合成一个复杂地图形。我们一般在下来场景中使用子图:

  1. 数据可视化:将多个数据集在同一张图中显示,进行对比和分析。
  2. 图表组合:将多个图表组合在一起,形成一个综合性图形。
  3. 数据分析:将多个数据集在同一张图中显示,进行筛选。
  4. 可视化规范化:将多个来源不同地数据集放在同一张图中显示,保证图形地一致性和准确性。

3 坐标轴

matplotlib的坐标中是用于在绘图中表示数据的位置的工具。坐标轴是图像中的水平和垂直线,它们通常表示为x轴和y轴。坐标的作用是帮助观察者了解图中数据的位置和大小,通常有数字或标签,以指示特定的值在图像中的位置。

1)坐标轴范围

matplitlib绘制图形时,会自动根据X,Y轴的数值,自动确定其范围,确保能够涵盖所有的数值。

比如:

fig,ax = plt.subplots(2,1)

x = np.linspace(1,10,10)
y = np.random.randint(0,10,10)
ax[0].plot(x,y)

x = np.linspace(1,100,10)
y = np.random.randint(0,100,10)
ax[1].plot(x,y)

matplotlib基础--1_第13张图片

可以看出,图形中X轴,Y轴的范围是根据x,y列表中数值的最大值来生成的。有时候,为了看图的局部位置,可以主动设置X轴,Y轴的范围,而不是依靠自动生成。

比如:

fig, ax = plt.subplots(2,1)

x = np.array(range(0,8))
y = np.random.randint(1,100,8)
ax[0].set_xlim(3,6)
ax[0].plot(x,y)

y = np.random.randint(100,200,8)
ax[1].set_ylim(140,180)
ax[1].plot(x,y)

 matplotlib基础--1_第14张图片

 上面的示例设置第一个图的X轴范围,第二个图设置Y轴范围。

2) 双坐标轴

如果要把Y轴不同范围的两条曲线放在一起比较,就要用到双坐标轴。

如:

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
x = np.linspace(1,10,10)

y1 = np.random.randint(1,50,10)
y2 = np.random.randint(50,100,10)

ax.plot(x, y1, c='y')
ax.plot(x, y2, c='b')

matplotlib基础--1_第15张图片 上图中,黄色线条在0~50之间,蓝色线条在50~100之间。虽然放在一个图中比较,看着却如两个子图。这时,我们可以用两个不同的Y轴,从而能够让两条曲线更好的比较。

fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
ax_twinx = ax.twinx()
x = np.linspace(1,10,10)

y1 = np.random.randint(1,50,10)
y2 = np.random.randint(51,100,10)

ax.plot(x, y1, c='g')
ax.plot(x, y2, c='b')

matplotlib基础--1_第16张图片

 左边是绿线对应的Y轴,右边时蓝线对应的Y轴。

3) 反轴标轴

关于轴标轴的设置,还有一个比较常用的设置是反转坐标轴。坐标轴的默认顺序是从小到大,但是,对于一些特殊的图表类型(如果散点图、条形图、直方图等),可以通过反转坐标轴来更好地展示数据点地分布情况。

3.1 反转X轴
fig = plt.figure()

x = np.linspace(1,10,10)
y = np.random.randint(1,100,10)

ax1 = fig.add_subplot(211)
ax1.plot(x,y)

ax2 = fig.add_subplot(212)
ax2.invert_xaxis()
ax2.plot(x,y)

matplotlib基础--1_第17张图片

3.2 反转Y轴
fig = plt.figure()

x = np.linspace(1,10,10)
y = np.random.randint(1,100,10)

ax1 = fig.add_subplot(211)
ax1.plot(x,y)

ax2 = fig.add_subplot(212)
ax2.invert_yaxis()
ax2.plot(x,y)

matplotlib基础--1_第18张图片

 上例两个子图的Y轴顺序是相反的。

4)总结回顾

这里介绍的主要轴标轴在展示分析结果的不同场景中常用的设置方法,其它关于坐标轴字体,颜色等可以查阅官方文档。

4 刻度

matplotlib中刻度是用于在绘图中表示数据大小的工具。刻度是坐标轴上的数字或标签,用于指示数据的大小或值,通常以整数或小数表示,具体取决于坐标轴的类型和限制。

默认的绘制时,坐标轴只有默认的主要刻度,如下所示:

from matplotlib.ticker import MultipleLocator

x = np.linspace(1, 50 ,50)
y = np.random.randint(100,200, 50)

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])

w=ax.get_xaxis()
w.set_major_locator(MultipleLocator(20))
w.set_minor_locator(MultipleLocator(2))
v=ax.get_yaxis()
v.set_major_locator(MultipleLocator(50))
v.set_minor_locator(MultipleLocator(10))

ax.plot(x,y)

matplotlib基础--1_第19张图片

在上面示例中:

设置了X受的主要刻度间隔为20,次要刻度间隔2,也就是每2个主要刻度之间有10个次要刻度。

设置了Y轴的主要刻度间隔为50,次要刻度间隔10,也就是每2个主要刻度之间有5个次要刻度。

次要刻度就是上面图中主要刻度之间稍微短点的线。

2) 刻度样式

刻度的样式非常灵活,常见的有以下几种设置。

2.1 隐藏刻度

隐藏刻度,只保留图形,这在做某些示意图时可能会用到。

x=np.linspace(1,100,100)
y=np.random.randint(0,200,100)

fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])

xaxis=ax.get_xaxis()
yaxis=ax.get_yaxis()

xaxis.set_major_locator(plt.NullLocator())
yaxis.set_major_locator(plt.NullLocator())

ax.plot(x,y)

matplotlib基础--1_第20张图片

 2.2 密度

密度时指刻度的间隔,如果图比较小,可以设置间隔大一些,反之则设置小一些。

from matplotlib.ticker import MultipleLocator

x = np.linspace(1,100,100)
y = np.random.randint(100,200,100)

rows, cols = 2, 2
grid = plt.GridSpec(rows, cols)

ax = plt.subplot(grid[0,0])
ax.plot(x, y)
ax.xaxis.set_major_locator(MultipleLocator(20))
ax.yaxis.set_major_locator(MultipleLocator(50))

ax = plt.subplot(grid[1,:])
ax.plot(x, y)
ax.xaxis.set_major_locator(MultipleLocator(10))
ax.yaxis.set_major_locator(MultipleLocator(20))

matplotlib基础--1_第21张图片

 上例中,根据图形的大小,我们设置了刻度的不同密度。

2.3 颜色,大小,旋转

为了突出默写刻度值,有时候会需要修改那些刻度值的颜色和大小。

x = np.linspace(1,100,100)
y = np.random.randint(100,200,100)

fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
ax.xaxis.set_major_locator(MultipleLocator(10))

obj = ax.get_xticklabels()[2]
obj.set_size(20)
obj.set_color("pink")

ax.plot(x,y,c="y")

matplotlib基础--1_第22张图片

上面例子中,X轴刻度10被放大并且改成红色。

刻度的旋转一般在刻度内容比较长的情况下,比如下面的示例:

x=np.array([
    "2023-01-01",
    "2023-02-01",
    "2023-03-01",
    "2023-04-01",
    "2023-05-01",
    "2023-06-01",
    "2023-07-01",
    "2023-08-01",
    "2023-09-01",
    "2023-10-01",
    "2023-11-01",
    "2023-12-01",
])
y = np.random.randint(100,200,12)

fig = plt.figure()
ax = fig.add_axes([0.1, 0.1,0.8,0.8])

ax.plot(x,y, color="r")

matplotlib基础--1_第23张图片

 由于X轴的刻度是日期,因为太长,所以会挤在一起,显示不清。这时可以调整X轴的刻度的角度,避免重合在一起。

x=np.array([
    "2023-01-01",
    "2023-02-01",
    "2023-03-01",
    "2023-04-01",
    "2023-05-01",
    "2023-06-01",
    "2023-07-01",
    "2023-08-01",
    "2023-09-01",
    "2023-10-01",
    "2023-11-01",
    "2023-12-01",
])
y = np.random.randint(100, 200, 12)

fig = plt.figure()
ax = fig.add_axes([0.1, 0.1,0.8,0.8])
plt.xticks(rotation=60)
ax.plot(x,y, color="r")

matplotlib基础--1_第24张图片

2.4 latex格式

matplotlib的刻度还支持latex格式,可以显示一些特殊的字符,比如圆周率pi。

直接显示时:

x = np.array([0, np.pi/6, np.pi/4, np.pi/3, np.pi/2])
x = np.round(x,2)
y = np.sin(x)

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
plt.xticks(labels=x, ticks=x)
ax.plot(x,y)

matplotlib基础--1_第25张图片

X轴的刻度显示实际的值。

调整为latex格式显示:(调整plt.xticks()这个函数)

x = np.array([0, np.pi/6, np.pi/4, np.pi/3, np.pi/2])
y = np.sin(x)

fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
plt.xticks(labels=["0","$\pi/6$","$\pi/4","$\pi/3$","$\pi/2$"], ticks=x)
ax.plot(x,y)

matplotlib基础--1_第26张图片

 X轴的刻度中显示圆周率pi,更易于阅读和理解。

3) 总结回顾

与之前介绍的画布,子图和坐标轴相比,刻度时设置最多也是最复杂的一个容器。刻度的主要作用是帮助数组可视化更加清晰和易于理解,基于此,本节介绍了:

  • 主次刻度
  • 刻度样式,包括是否显示刻度,刻度的密度,颜色,大小,角度和latex公式的支持。

你可能感兴趣的:(python,matplotlib)