在matplotlib中使用图,轴或图形绘制图之间有什么区别?


99

当我在matplotlib,tbh中绘制图时,我有点困惑后端的处理方式,我不清楚图,轴和图形的层次结构。我阅读了文档,它很有帮助,但我仍然感到困惑...

以下代码以三种不同的方式绘制相同的图:

#creating the arrays for testing
x = np.arange(1, 100)
y = np.sqrt(x)
#1st way
plt.plot(x, y)
#2nd way
ax = plt.subplot()
ax.plot(x, y)
#3rd way
figure = plt.figure()
new_plot = figure.add_subplot(111)
new_plot.plot(x, y)

现在我的问题是-

  1. 这三种方法有什么区别,我的意思是,当调用这三种方法中的任何一种时,幕后情况是什么?

  2. 什么时候应该使用哪种方法,在这些方法上使用利弊是什么?


8
我已经读过了,但是根本没有找到满意的答案。它解释了层次结构,但也引起了混乱,为什么没有传统的方式,为什么图形对象甚至暴露出来?
hashcode55 2013年

我不确定您是否参考了这个确切的文档matplotlib.org/users/artists.html。这回答了您为什么还要暴露图形的问题。就个人而言,这是我发现的matplotlib的最佳解释。Figure对象使您可以直接添加自己的Artists,而无需使用坐标轴,尽管很少使用它,除非您要调整图形本身的“补丁”等。请注意,Figure是父容器,并承载着axis&artists。
桑迪普

Answers:


54

方法1

plt.plot(x, y)

这样一来,您只能绘制一个具有(x,y)坐标的图形。如果您只想获取一张图形,则可以使用这种方式。

方法2

ax = plt.subplot()
ax.plot(x, y)

这使您可以在同一窗口中绘制一个或多个图形。在编写时,您将仅绘制一个图形,但是可以进行如下操作:

fig1, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)

您将绘制4个图形,每个图形分别命名为ax1,ax2,ax3和ax4,但在同一窗口上。在我的示例中,此窗口将分为四个部分。

方法3

fig = plt.figure()
new_plot = fig.add_subplot(111)
new_plot.plot(x, y)

我没有使用它,但是可以找到文档。

例:

import numpy as np
import matplotlib.pyplot as plt

# Method 1 #

x = np.random.rand(10)
y = np.random.rand(10)

figure1 = plt.plot(x,y)

# Method 2 #

x1 = np.random.rand(10)
x2 = np.random.rand(10)
x3 = np.random.rand(10)
x4 = np.random.rand(10)
y1 = np.random.rand(10)
y2 = np.random.rand(10)
y3 = np.random.rand(10)
y4 = np.random.rand(10)

figure2, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
ax1.plot(x1,y1)
ax2.plot(x2,y2)
ax3.plot(x3,y3)
ax4.plot(x4,y4)

plt.show()

在此处输入图片说明 在此处输入图片说明

其他例子:

在此处输入图片说明


@ hashcode55每个数字都是独立的。我将向您展示一个示例
Essex

1
@ hashcode55我将用一个示例进行编辑(只是我在天体物理学研究中得出的数字,脚本太长(1300行););每个数字都是独立的;)
Essex

3
我知道这很挑剔,但我这样做是因为matplotlib语言让我感到困惑,并且在搜索“ matplotlib中的轴与图形”时会出现此问题。对于其他菜鸟来说,这个问题有助于回答这一问题。我认为这里的措词可能会更清楚,subplots()Axes单个对象返回对象figure
亨迪

34

对象名称

Matplotlib严格面向对象,其主要对象是图形(我发现这个名称axes有些误导,但可能只是我一个人)。

您可以将图形视为画布,通常指定其尺寸,并可能指定背景颜色等。您可以通过两种方式使用画布,图形,在其上放置其他对象(主要是,但是以及文本标签等),然后使用保存其内容savefig

你可以把中轴线作为一种瑞士军刀,一个方便的对象,提供了一个工具(例如.plot.scatter.hist等)的一切,大部分。您可以使用多种不同的方法之一在图形中放置一,二,...多个

plt接口

PLT程序接口最初是模仿MATLAB™接口,但不是从面向对象的接口确实不同,即使你不直接引用的主要对象(即数字),这些对象自动将其实例化,并且每个plt方法实质上都转换为对基础对象的方法之一的调用:例如,aplt.plot()是a hidden_axes.plot,aplt.savefig是a hidden_figure.savefig

在任何时候,您都可以使用plt.gcf和来处理这些隐藏对象plt.gca,并且当其中一个对象方法尚未移植到plt名称空间中的方法时,有时这是必需的。

我想补充一点,plt名称空间还包含许多方便的方法,可以用不同的方式实例化图形

你的例子

第一种方式

plt.plot(x, y)

在这里,您仅使用plt界面,每个图中只能使用一个,但这就是您在探索数据时想要的,这是完成工作的快速方法...

第二路

ax = plt.subplot()
ax.plot(x, y)

在这里,您可以使用plt命名空间中的便捷方法为您的axes对象指定名称(和句柄),但顺便说一句,还有一个隐藏的图形。您以后可以使用axes对象来绘制,制作直方图等,可以使用plt界面进行所有操作,但是您还可以访问其所有属性并以更大的自由度对其进行修改。

第三种方式

figure = plt.figure()
new_plot = figure.add_subplot(111)
new_plot.plot(x, y)

在这里,您开始使用plt名称空间中的便捷方法实例化图形,然后仅使用面向对象的接口。

可以绕过plt便捷方法(matplotlib.figure.Figure),但是您必须调整图形以获得更好的交互体验(毕竟,这是一种便捷方法)。

个人推荐

我建议在交互式会话的环境中使用裸露plt.plotplt.scatter可能使用IPython及其%matplotlib魔术命令,也建议在探索性的Jupyter笔记本环境中使用。

另一方面,面向对象的方法以及一些plt 便捷的方法是必经之路

  • 如果您有一个永久性的问题,可以通过微调的子图的自定义安排彻底解决所有问题,
  • 如果要将Matplotlib嵌入在编写的程序的UI中。

这些极端之间有一个很大的灰色区域,如果您问我该怎么办,我只会说“这取决于” ...


2
“我发现名称轴有点误导,但可能只是我一个人”-不,也是我。但是不能更改。
Laryx Decidua

1
另一件事我就是无法理解为什么人们想要子图fig, ax = plt.subplot()时会使用这个成语。在这种情况下,我发现“过程式”样式更容易。“但是可能只是我...” :-)
Laryx Decidua

@LaryxDecidua我可以立即看到两个很好的理由①“显式比隐式更好”②您要使用过程API中不可用的Figure或Axes方法-但可能还有其他方法…
gboffi

是的,我完全同意1)。关于2):大多数情况下,过程API就足够了。归根结底,我认为这归结为个人喜好–人们不应该争论:-)
Laryx Decidua
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.