器→工具, 工具软件, 数据, 术→技巧

Matplotlib初级入门教程

钱魏Way · · 717 次浏览

Matplotlib简介

MATLAB

MATLAB是Matrix & Laboratory两个词的组合,意为矩阵工厂(矩阵实验室)。是由美国 Mathworks公司发布的主要面对科学计算、可视化以及交互式程序设计的高科技计算环境。

它将数值分析、矩阵计算、科学数据可视化以及非线性动态系统的建模和仿真等诸多强大功能集成在一个易于使用的视窗环境中,为科学研究、工程设计以及必须进行有效数值计算的众多科学领域提供了一种全面的解决方案,并在很大程度上摆脱了传统非交互式程序设计语言(如C、Fortran)的编辑模式,代表了当今国际科学计算软件的先进水平。

Matplotlib

Matplotlib是Python中使用最广泛的数据可视化库。Matplotlib最早由John Hunter于2002年启动开发,其目的是为了构建一个Matlab式的绘图函数接口。它利用了 Python 下的数值计算模块 Numeric 及 Numarray,克隆了许多 Matlab 中的函数, 用以帮助用户轻松地获得高质量的二维图形。

Matplotlib 可以绘制多种形式的图形包括普通的线图,直方图,饼图,散点图以及误差线图等;可以比较方便的定制图形的各种属性比如图线的类型,颜色,粗细,字体的大小等;它能够很好地支持一部分 TeX 排版命令,可以比较美观地显示图形中的数学公式。

Matplotlib 掌握起来也很容易,由于 Matplotlib 使用的大部分函数都与 Matlab 中对应的函数同名,且各种参数的含义,使用方法也一致,这就使得熟悉 Matlab 的用户使用起来感到得心应手。对那些不熟悉的 Matlab 的用户而言,这些函数的意义往往也是一目了然的,因此只要花很少的时间就可以掌握。

多年来,我常常使用 MATLAB 进行数据分析和可视化。 MATLAB 擅长绘制漂亮的图形。当我开始处理 EEG 数据时,我发现我需要编写应用程序来与我的数据交互,并在 MATLAB 中开发了一个 EEG 分析应用程序。随着应用程序越来越复杂,需要与数据库,http 服务器交互,并操作复杂的数据结构,我开始与 MATLAB 作为一种编程语言的限制而抗争,并决定迁移到 Python。 Python 作为一种编程语言,弥补了 MATLAB 的所有缺陷,但我很难找到一个 2D 绘图包(3D VTK 则超过了我的所有需求)。

当我去寻找一个 Python 绘图包时,我有几个要求:

  • 绘图应该看起来不错 – 发布质量。 对我来说一个重要的要求是文本看起来不错(抗锯齿等)
  • 用于包含 TeX 文档的 Postscript 输出
  • 可嵌入图形用户界面用于应用程序开发
  • 代码应该足够容易,我可以理解它,并扩展它
  • 绘图应该很容易

没有找到适合我的包,我做了任何自称 Python 程序员会做的事情:撸起我的袖子开始自己造。我没有任何真正的计算机图形经验,决定模仿 MATLAB 的绘图功能,因为 MATLAB 做得很好。这有额外的优势,许多人有很多 MATLAB 的经验,因此,他们可以很快开始在 python 中绘图。从开发人员的角度来看,拥有固定的用户接口(pylab 接口)非常有用,因为代码库的内容可以重新设计,而不会影响用户代码。

Matplotlib架构

Matplotlib 架构从逻辑上分为三层,位于三个不同的层级上。上层内容可以与下层内容进行通讯,但下层内容不可以与上层内容通讯。三层从上至下依次是:

  • Scripting(脚本层)
  • Artist(表现层)
  • Backend(后端层)

它们之间的访问关系是:Scripting 访问 Artist, Artist 访问 Backend

Backend 层

Backend 为最底层,即 matplotlib API 层。Backend在mpl.backend_bases类下,其中包含了各种键盘、鼠标的Event类、用以绘制线段、图形的RenderBase类、负责将Figure对象和其输出分离开的FigureCanvasBase类等(只是一个接口,具体不同输出,比如PDF、PNG的定义在backends类中)。即所有派生/输出的方法都放在mpl.backends下,比如Qt5后端为mpl.backends.qt5agg。输出PDF的后端为mpl.backend_pdf,这里的类负责和不同的后端/平台进行交互。这样的设计保证了代码的解耦和设计的统一。

不同的后端提供了不同的API,其在backends类中定义,这一层包含了 matplotlib 的 API,也就是若干类的集合,这些类用来在底层实现各种图形元素。主要包括:

  • FigureCanves:用来表示图形的绘制区域
  • Renderer:用来在 FigureCanves 上绘制内容的对象
  • Event:用来处理用户输入(键盘、鼠标输入)的对象

Artist 层

如果说Backend层做的事情是确立了一个Canvas、Renderer、Event的架构,那么Artist层所做的事情就是告诉程序,在Renderer上画什么东西到Canvas上。这一层不用接触后端,不用关系不同实现方法的差异,只需要告诉Backend层需要draw的内容即可。

所有的元素都是mpl.artist.Artist类的实例/子类。Artist Module包含大量已经定义的元素,包括Tick刻度、Text文本、Patch复合图形(坐标轴、阴影、圆、箭头、Rectangle等)、Figure图形、Legend标签、Line2D线段、Axis坐标轴、Axes复合坐标轴。artist Module中的元素通过draw方法和backend Module进行交互和信息传递,传递是单向的。

整个架构的中间层,所有用来构成一个图像的各种元素都在这里,比如标题、坐标轴、坐标轴标签、标记等内容都是 Artist 的实例。并且这些元素构成了一个层级结构。

Artist 层拥有许多可视化元素,即标题、轴标签、刻度等元素。Artist 分为两类,一类是Primitive Artist,一类是Composite Artist:

  • Primitive Artist 是包含基本图形的独立元素,例如一个矩形、一个圆或者是一个文本标签
  • Composite Artist 是这些简单元素的组合,比如横坐标、纵坐标、图形等

在处理这一层内容的时候,主要打交道的都是上层的图形结构,需要理解其中每个对象在图形中所代表的含义。下图表示了一个 Artist 对象的结构。

Artist 最上层是 Figure 层,表示图形概念; Axes 在 Figure 上面,表示轴的作图的内容(即轴对象),每个维度会有一个 Axes 对象;Axis 用来展示 Axes 上的数值(即刻度与刻度值),刻度的位置用 Locator 对象管理,刻度的标签的格式用 Formatter 对象调整。

Scripting 层

如果说上一层代表了HTML,那么这一层就代表了JavaScript,你可以将这一层看作带有状态保持的交互界面。比如Python的那个交互解释器一样。mpl.pyplot是这一层的全部入口。

该层包含了一个 pyplot 接口。这个包提供了经典的 Python 接口,基于编程的方式操作 matplotlib,它有自己的命名空间,需要导入 NumPy包。

使用Matplotlib Layers绘制图形

使用Artist Layer 绘图

# Step One: We import FigureCanvas from Back-end layer.
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas

# Step two: We import Figure Artist
from matplotlib.figure import Figure

# Step 3: We create a Figure object using the constructor
fig = Figure()

import numpy as np
np.random.seed(6)
x = np.random.randn(20000)

# Next we create an Axes Artist object.
ax = fig.add_subplot(111)

# Next we call the Axes method hist() function.
ax.hist(x, 100)

# Finally we assign a title to the plot.
ax.set_title('Artist Layer Histogram')

# And we save it, in this case as a PNG file. 
fig.savefig('Matplotlib_histogram.png')

  • ax = fig.add_subplot(111):遵循MATLAB公约。创建一个包含一行、一列的网格,并使用网格中的第一个单元格作为执行对象的位置。
  • ax.hist(x,100):为每个柱状图条创建一个矩形原始Artistlayer对象序列,并将它们添加到ExesContainer中。100个意味着产生100个柱状图条。

使用Scripting Layer 绘图

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

np.random.seed(6)
X = np.random.randn(20000)

plt.hist(X, 100)
plt.title('Scripting Layer Histogram')
plt.savefig('matplotlib_histogram.jpg')

Artist 还是 Scripting Layer?

显然,使用Scripting layer (matplotlib.pyplot) 相对而言更加易用,轻量,语法也更加简单。虽然Artist layer是专业的开发人员的首选。但是最好两者都掌握。

Matplotlib图像结构

  • Canvas(画板)位于最底层,用户一般接触不到
  • Figure(画布)建立在Canvas之上
  • Axes(绘图区)建立在Figure之上
  • 坐标轴(axis)、图例(legend)等辅助显示层以及图像层都是建立在Axes之上

容器层

容器层主要由Canvas(画布)、Figure(图形,绘图区)、Axes(轴)

  • Canvas(画布)底层的系统层,在绘图的过程中充当画板的角色,即放置Figure(绘图区)的工具
  • Figure是Canvas上方的第一层,也是需要用户来操作的应用层的第一层,在绘图的过程中充当画布的角色。
  • Axes是应用层的第二层,在绘图的过程中相当于画布上的绘图区的角色。
  • Figure:指整个图形(可以通过figure()设置画布的大小和分辨率等)
  • Axes(坐标系):数据的绘图区域
  • Axis(坐标轴):坐标系中的一条轴,包含大小限制、刻度和刻度标签

特点为:

  • 一个figure(画布)可以包含多个axes(坐标系/绘图区),但是一个axes只能属于一个figure。
  • 一个axes(坐标系/绘图区)可以包含多个axis(坐标轴),包含两个即为2d坐标系,3个即为3d坐标系

辅助显示层

辅助显示层为Axes(绘图区)内的除了根据数据绘制出的图像以外的内容,主要包括

  • Axes外观(facecolor)
  • 边框线(spines)
  • 坐标轴(axis)
  • 坐标轴名称(axis label)
  • 坐标轴刻度(tick)
  • 坐标轴刻度标签(tick label)
  • 网格线(grid)
  • 图例(legend)
  • 标题(title)

该层的设置可使图像显示更加直观更加容易被用户理解,但又不会对图像产生实质的影响。

图像层

图像层指Axes内通过

  • plot(折线图)
  • scatter(散点图)
  • bar(柱状图)
  • histogram(直方图)
  • pie(饼图)

使用PYPLOT进行绘图

plt.plot()绘图

快速上手plot()绘图

这种图形绘制方法是完全的通过pyplot解释层进行绘图。当调用plt.plot()方法的时候,如果系统没有检测到存在Figure对象和Axes对象,则会创建一个,如果检测到,则直接使用。创建后选择的后端为默认后端,canvas一般为mpl.backends.backends_xxagg类。

plt.plot(np.random.randn(50).cumsum(), 'r--.')

pyplot.plot 可以接受绘制对象和一些类似于命令行的参数,可选颜色、点线状态(水平线、垂直线、星标)等各种形状。plot的参数参见Line 2D,可以这样指定:

plot(x, y, color='green', linestyle='dashed', marker='o',markerfacecolor='blue', markersize=12)

pyplot可以直接按照面向过程方式处理,调用plt.axis会对当前Axes中的axis属性进行设置。

import matplotlib.pyplot as plt

plt.plot([1,2,3,4], [2,21,23,11], "r^", [12,21,43,21], "b", [0,2,12,40,18], "y--")#x轴、y轴和其颜色、类型、第二个y轴和其颜色、类型、第三个y轴和其颜色、类型
plt.title("My First plt Figure")
plt.axis([-1,5,-10,50]) #sets the min and max of the x and y axes, with v = [xmin, xmax, ymin, ymax]
plt.show()

子图形、标签、刻度、文本

通过面向过程的方法,我们可以快速进行图像绘制,其中有一些比较重要的方法,比如:

  • subplot(m,n,a) 在一个Figure和Axes上绘制多个图形,你可以在任何时候返回这个子图进行修改。
  • subplots_adjust() 快速调整图形间距
  • title() 设置标题
  • grid() 设置网格
  • xlabel() 设置x轴标签
  • xticks() 设置x轴刻度
  • legend() 控制图例显示
  • text() 在指定位置放置文本
from matplotlib.ticker import NullFormatter
import numpy as np

# 设置x轴和y轴的数据
t = np.arange(0, 5, 0.1)
y1 = np.sin(2 * np.pi * t)
y2 = np.sin(2 * np.pi * t)

# 设置整体图形外观
plt.subplots_adjust(top=2, bottom=0.08, left=0.10, right=0.95, hspace=0.25, wspace=0.35)

# plt.title("My First plot") not work here
# 设置第一个子图形的标题、绘图、标签、网格
plt.subplot(411)  # 用来水平切分4个,垂直切分1个,调用第1个图形
plt.title("My First plot", fontsize=14)  # only work here
plt.plot(t, y1, "b-.")  # 在这里还可以设置绘制的点的样式、颜色等
plt.ylabel("Value-M1")
plt.grid(True)

# 同上,调用第二个图形,设置文本和图例
plt.subplot(412)
plt.plot(t, y2, "r--")
plt.ylabel("Value-M2")
plt.text(1, 0.5, "text1")
plt.text(3, 0.3, "text2")
plt.legend(["Legend"], loc=1)  # 图例位置和文本内容

# 同上,调用第三个图形,gca返回当前instance,设置刻度
plt.subplot(413)
plt.plot(t, y1, "p-.")
plt.gca().xaxis.set_minor_formatter(NullFormatter())  # gca获取当前axes,set..设置刻度

plt.subplot(411)
# 你可以在任意时候,回到之前绘制的子图中继续在其上绘制其他图案。比如:
# plt.plot(t,y1,"p-.") #这条命令会绘制在图1中,并且和之前图1存在的内容并存
plt.show()

Figure和Axes:图形、子图形和其轴

Figure和Axes对象

class matplotlib.figure.Figure
(figsize=None, dpi=None, facecolor=None, edgecolor=None, linewidth=0.0, frameon=None, subplotpars=None, tight_layout=None)

Figure还有很多方法,常有的有:

  • add_axes(rect) 添加子轴
  • add_subplot(mna) 添加子图
  • clear() 清除图像
  • draw(renderer) 底层接口
  • gca() 当前Axes
  • get_children() 获取子元素
  • hold() 丑陋的MATLAB兼容性
  • savefig() 保存图片
  • set_canvas() 底层接口
  • show() 显示图片
  • subplots_adjust() 子图微调
  • text() 放置文字
class matplotlib.axes.Axes
(fig, rect, facecolor=None, frameon=True, sharex=None, sharey=None, label='', xscale=None, yscale=None, axisbg=None, **kwargs)

Axes有很多方法,单独方法大约有100种,因此在这里不再举例,可查阅手册。

调用和创建Figure和Axes对象

使用plt进行绘图固然很方便,但是有时候我们需要细微调整,一般需要使用:

  • gca() 返回当前状态下的Axes对象,Fig.gca()的Alias
  • gca().get_children() 方便查看当前Axes下的元素
  • gcf() 返回当前状态下的Figure对象,一般用以遍历多个图形的Axes(plt.gcf().get_axes())。另一种方法是使用Axes矩阵的索引抽取子Plot的Axes。

对于想要重新画一幅图,而不是将图形绘制在一个Figure中并且区分成几个subplot,直接使用plt.figure()创建一个新的Figure对象,使用plt.gcf()也可以捕获这个对象。每个图形可以有很多子图形构成,每个子图形只有一个Axes,它们可以共享坐标轴,每个子图形都有其各自的AxesSubplot子轴,包含在总的Axes中。

正比如Figure对象和Canvas对象的交互用 canvas = FigureCanvasBase(fig) 进行操作一样,Figure对象和Axes对象的关联可以使用下面几种方法:

  • axes = plt.subplot(mna) #MATLAB方式,一般仅用作交互,而不捕获输出
  • axes = mpl.axes.Axes(fig,*kwargs #OOP方式,较少使用
  • fig, axes_martix = plt.subplots(nc,nr) #快速方式,适合快速创建Figure对象和Axes对象,一般用于创作指定子图形个数的图。
  • axes = fig.add_subplot(mna) #适合在有Figure对象情况下创建单个子图形,和subplot()类似。相比较subplots,其优点在于可以使用gridspec绘制带有X-Y轴附属图形的图。
  • axes = fig.add_axes([rect]) #适合在一个图形指定位置添加一个小的子图形和其Axes。一般用作附属图形的绘制。

一个例子:OOP方式

from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure() #调用一个新的画布
fig2 = plt.gcf() # fig2 == fig1 => True

ax_sub = fig.add_subplot(2, 2, 1) #添加子画布,2×2大小,第一个
ax_sub2 = fig.add_subplot(2, 2, 2) #添加子画布,2×2大小,第二个
ax_sub3 = fig.add_subplot(2, 2, 3) #添加子画布,2×2大小,第三个
# 需要注意,add_subplot返回的是sub axes对象

一个例子:plt.subplots方式

%matplotlib inline
x = np.arange(0.1, 4, 0.5)
y = np.exp(-x)
#快速创建图形 Fig 和 Axes Martix
fig, ax = plt.subplots(3, 3, sharex=True, sharey=True)
#或者使用 fig, ((ax1,ax2,ax3),(ax4,ax5,ax6),(ax7,ax8,ax9)) = plt.subplots(3,3)
print(ax)

# plot the linear_data on the 5th,8th subplot axes
ax[2][2].plot(x,y, '-')
ax[1][1].plot(x,y**2, '-')

# 对于一个包含多个轴的fig,可以使用 gcf().get_axis,或者直接对矩阵进行索引和操纵
for ax in plt.gcf().get_axes():
    for label in ax.get_xticklabels() + ax.get_yticklabels():
        label.set_visible(True)
        
# necessary on some systems to update the plot
plt.gcf().canvas.draw()

[[<matplotlib.axes._subplots.AxesSubplot object at 0x7f57f8c3b310>
  <matplotlib.axes._subplots.AxesSubplot object at 0x7f57f8bec110>
  <matplotlib.axes._subplots.AxesSubplot object at 0x7f57f86c11d0>]
 [<matplotlib.axes._subplots.AxesSubplot object at 0x7f57f8b16290>
  <matplotlib.axes._subplots.AxesSubplot object at 0x7f57f84e7350>
  <matplotlib.axes._subplots.AxesSubplot object at 0x7f57f86ed410>]
 [<matplotlib.axes._subplots.AxesSubplot object at 0x7f57f8ca8a10>
  <matplotlib.axes._subplots.AxesSubplot object at 0x7f57f857ecd0>
  <matplotlib.axes._subplots.AxesSubplot object at 0x7f57f855ce50>]]

绘图常用方法

Firure常用方法

  • subplots_adjust等同于调用subplots_adjust(left=None, bottom=None, right=None, top=None,wspace=None, hspace=None)顶级函数,用于调整子plot周围宽度、高度等表现形式。
  • savefig(fname,dpi,bbox_inches,format)保存图像

Axes常用方法

  • hist 柱状图/pie 饼状图/box 箱型图等等
  • plot 如果不指定图的类型,比如饼状图或者柱状图,直接传入plot,参数填为data即可。
  • add_patch 添加图形
  • annotate 添加箭头
  • text 添加文本说明
  • get(set)_x(y)lim 获得/设置不同轴的范围
  • g/s_(x/y)ticks 设置刻度位置 #plt.xticks((0,1,2),(“a”,”b”,”c”)) 可以快速指定位置和标签值。
  • g/s_(x/y)ticklabels 设置刻度标签
  • g/s_(x/y)label 设置轴名称
  • title 题头设置
  • legend 图例设置

对于Axes调用get/set等很多方法,其实也可以直接调用plt全局对象,不过调用axes单个元素可以获得更精细的控制,并且更面向对象一些。

fig, ax = plt.subplots(2, 3, sharex=True, sharey=True)
fig.subplots_adjust(left=None, bottom=None, right=None, top=None,wspace=0, hspace=0) 
#也可以使用plt顶级函数
#histogram 柱状图
ax[0,0].hist(np.random.randint(1,500,size=100),bins=50,color="k",alpha=0.5)
ax[0,1].hist(np.random.randint(1,500,size=100),bins=50,color="k",alpha=0.5)
ax[0,2].hist(np.random.randint(1,500,size=100),bins=50,color="k",alpha=0.5)
ax[1,0].hist(np.random.randint(1,500,size=100),bins=50,color="k",alpha=0.5)
ax[1,1].hist(np.random.randint(1,500,size=100),bins=50,color="k",alpha=0.5)
ax[1,2].hist(np.random.randint(1,500,size=100),bins=50,color="k",alpha=0.5)

fig.savefig("hello.png",format="png", dpi=100,bbox_inches="tight")
#两个较为重要的参数是bbox_inches控制边距,第二个是dpi控制精度

fig,ax = plt.subplots()
ax.plot(np.random.randn(500).cumsum(),label="a") 
#此处设置plot的label值,即可以调用legend时自动生成图例。
ax.plot(np.random.randn(500).cumsum(),label="b")
ax.set_xticks([0,150,300,450,600])
ax.set_xticklabels(["one","two","three","four","five","six"]) #自动跳过了six
#也可以直接写ax.xticks([真实数值],[对应标签名称])
ax.set_title("table",loc="center")
ax.set_xlabel("numbers")
ax.set_ylabel("values")
ax.legend(loc="best") #legend图例,在plot时传入label进行创建
ax.text(0,10,"Hello World")
# matplotlib.pyplot.text(x, y, s, fontdict=None, withdash=False, **kwargs)
ax.annotate("", xy=(0, 0), xycoords='data', xytext=(400,10), textcoords='data', arrowprops=dict(arrowstyle="->", connectionstyle="arc3"),)

SPINES坐标系绘制

%matplotlib inline
fig ,ax = plt.subplots()
x = np.arange(-2*np.pi,2*np.pi,0.01)
y = np.sin(3*x)/x
y2 = np.sin(2*x)/x
y3 = np.sin(x)/x

ax.plot(x,y,"r")
ax.plot(x,y2,"b")
ax.plot(x,y3,"g")

print(plt.gca(),ax)
# AxesSubplot(0.125,0.125;0.775x0.755) AxesSubplot(0.125,0.125;0.775x0.755)

ax.spines["right"].set_visible(False)
#class matplotlib.spines.Spine(axes, spine_type, path, **kwargs)
ax.spines["top"].set_visible(False)
ax.spines["bottom"].set_position(("data",0))
ax.spines["left"].set_position(("data",0))

PATCH图形的绘制

图形绘制需要调用axes.add_patch()方法,传入参数为图形,也就是line/path/patches对象。和Qt图形绘制很类似,底层API。

import matplotlib.path as mpath
import matplotlib.patches as mpatches
fig = plt.figure(figsize=(12,6))
axes = fig.add_subplot(1,2,1)
grid = np.mgrid[0.2:0.8:3j, 0.2:0.8:3j].reshape(2, -1).T
patches = []
# add a circle
circle = mpatches.Circle(grid[0], 0.1, ec="none")
patches.append(circle)
# add a rectangle
rect = mpatches.Rectangle(grid[1] - [0.025, 0.05], 0.05, 0.1, ec="none")
patches.append(rect)
axes.add_patch(patches[0]);axes.add_patch(patches[1])

AXES3D图表绘制

from mpl_toolkits.mplot3d import Axes3D

x = np.arange(8)#生成数据
y = np.random.randint(0,10,8)
y2 = y + np.random.randint(0,3,8)
y3 = y2 + np.random.randint(0,3,8)
y4 = y3 + np.random.randint(0,3,8)
y5 = y4 + np.random.randint(0,3,8)

fig = plt.figure() ; ax = Axes3D(fig) #普通方法调用fig和ax
#或者采用ax = fig.add_subplot(111, projection='3d')绘制子图形。
# For those using older versions of matplotlib, 
#change ax = fig.add_subplot(111, projection='3d') to ax = Axes3D(fig).

ax.bar(x,y,0,zdir="y")#数据和作为第三轴的轴:y
ax.bar(x,y2,10,zdir="y")
ax.bar(x,y3,20,zdir="y")
ax.bar(x,y4,30,zdir="y")
ax.bar(x,y5,40,zdir="y")
ax.set_xlabel("X label")#标签
ax.set_ylabel("Y label")
ax.set_zlabel("Z label")
ax.view_init(elev=50)#视角
ax.grid(False)
#3D设置在class mpl_toolkits.mplot3d.axes3d.Axes3D(fig, rect=None, *args, **kwargs)

子图网格和多面板绘图

区别与fig.add_subplot(),使用fig.add_axes()方法手动创建一个新的Axes,但是并没有制定该Axes的位置,需要手动指定,一般用作附属图形的绘制,之后调用此子axes,就可以对附属图形进行绘制了。

fig = plt.figure()
ax_1 = fig.add_axes([0.1,0.1,1,1]) #此处定义的是图表的 rect [left, bottom, width, height]
ax_2 = fig.add_axes([0.7,0.7,0.3,0.3])
ax_1.plot(np.random.randint(0,10,50),"ro")
ax_2.plot(np.random.randint(0,10,3),"g--")

在前面add_subplot()的介绍中,可以在此定义“12X”表示水平划分1个,垂直划分2个,选取第X个。但是,为了精确控制位置,可以使用GridSpec对象,传入一个方格大小,然后对其进行切片调用,作为参数传递给add_subplot(),这样就可以进行精细的子图控制。

fig = plt.figure()
gs = plt.GridSpec(3,3) #新建一个网格
fig.add_subplot(gs[1,:2]).plot(np.random.randint(0,10,10),"o") #不再传入1,2,1,而是传入
s2 = fig.add_subplot(gs[0,:2])
s2.plot(np.random.randint(0,10,10),"o")
fig.add_subplot(gs[2,0]).plot(np.random.randint(0,10,10),"o")
fig.add_subplot(gs[:2,2]).plot(np.random.randint(0,10,10),"o")
fig.add_subplot(gs[2,1:]).plot(np.random.randint(0,10,10),"o")

下面是一个应用Gridspec的例子:

from matplotlib.gridspec import GridSpec
import numpy as np

fig = plt.figure()
gs = GridSpec(3,3)
main = fig.add_subplot(gs[1:,1:])
hist = fig.add_subplot(gs[1:,0:1])
hist_x = fig.add_subplot(gs[0:1,1:])

data_x = np.random.random(size=10000)
data_y = np.random.normal(size=10000)

main.scatter(data_x,data_y)
main.set_xlim(0,1)
hist.hist(data_y,orientation='horizontal',bins=1000) #水平显示
hist.invert_xaxis() #反转X轴以方便比较数据
hist_x.hist(data_x,bins=1000)
hist_x.set_xlim(0,1)

GCA高级用法

使用plt.gca()可以精细控制绘图,比如:

plt.gca().fill_between(x,y1,y2,alpha,color)

可以绘制两条曲线组成的填充图形,在表示面积的时候很有用,比如积分面积。此外,还可以这样使用:

xaxis = plt.gca().get_xaxis() #从AXES实例中获取XAXIS实例

for item in xaxis.get_ticklabels(): #从XAXIS实例中获取TICKLABELS
    item.set_alpha(1) #TICKLABELS由TEXT实例构成,TEXT实例有很多方法
    item.set_rotation(45)
    item.set_backgroundcolor('r')
    item.set_color('w')

gca()本质上是一个Axes对象,查阅文档可以看出,这个对象具有很多可用的方法,比如本例中取出x子轴,并且对此轴的刻度标签进行遍历(Text对象),设置旋转、透明度和颜色、背景,对于较长的时间日期,这样可以使得坐标轴文字不挤在一起。

Matplotlib样式

使用matplotlib自带的几种美化样式,就可以很轻松的对生成的图形进行美化。可以使用matplotlib.pyplot.style.available获取所有的美化样式:

import matplotlib.pyplot as plt
print(plt.style.available)

具体官网查看样式参考表

使用自带的样式进行美化:

import matplotlib.pyplot as plt
plt.style.use('ggplot')
# 使用自定义样式:
plt.style.use('./images/presentation.mplstyle')
plt.style.use('https://github.com/dhaitz/matplotlib-stylesheets/raw/master/pitayasmoothie-light.mplstyle')

参考链接:

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注