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

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

当我在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. 什么时候应该使用哪种方法,在这些方法上使用利弊是什么?

I’m kind of confused what is going at the backend when I draw plots in matplotlib, tbh, I’m not clear with the hierarchy of plot, axes and figure. I read the documentation and it was helpful but I’m still confused…

The below code draws the same plot in three different ways –

#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)

Now my question is –

  1. What is the difference between all the three, I mean what is going under the hood when any of the 3 methods are called?

  2. Which method should be used when and what are the pros and cons of using any on those?


回答 0

方法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()

其他例子:

Method 1

plt.plot(x, y)

This lets you plot just one figure with (x,y) coordinates. If you just want to get one graphic, you can use this way.

Method 2

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

This lets you plot one or several figure(s) in the same window. As you write it, you will plot just one figure, but you can make something like this:

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

You will plot 4 figures which are named ax1, ax2, ax3 and ax4 each one but on the same window. This window will be just divided in 4 parts with my example.

Method 3

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

I didn’t use it, but you can find documentation.

Example:

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

Other example:


回答 1

对象名称

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中。

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

The names of objects

Matplotlib is strongly object oriented and its principal objects are the figure and the axes (I find the name axes a bit misleading, but probably it’s just me).

You can think of the figure as a canvas, of which you typically specify the dimensions and possibly e.g., the background color etc etc. You use the canvas, the figure, essentially in two ways, placing other objects on it (mostly axes, but also text labels etc) and saving its contents with savefig.

You can think of an axes as a sort of Swiss Army knife, a handy object that offers a tool (e.g. .plot, .scatter, .hist etc) for everything, mostly. You can place one, two, … many axes inside a figure using one of many different methods.

The plt interface

The plt procedural interface was originally developed to mimic the MATLAB™ interface but is not really different from the object oriented interface, even if you don’t make a direct reference to the main objects (i.e., a figure and an axes) these objects are automatically instantiated and each plt method is, essentially, translated to a call of one of the methods of the underlying fundamental objects: e.g., a plt.plot() is a hidden_axes.plot and a plt.savefig is a hidden_figure.savefig.

In every moment you can have an handle on these hidden objects using plt.gcf and plt.gca, and this is sometimes necessary when one of the object methods has not been ported to a method in the plt namespace.

I’d like to add that the plt namespace contains also a number of convenience methods to instantiate, in different ways, figure and axes.

Your examples

1st way

plt.plot(x, y)

Here you use only the plt interface, you can only use a single axes in each figure, but this is what you want when you are doing an exploration of your data, a quick recipe that gets the work done…

2nd way

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

Here you use a convenience method in the plt namespace to give a name (and a handle) to your axes object, but btw there is also an hidden figure. You can later use the axes object to plot, to make an histogram etc, all things that you can do with the plt interface, but you can also access all its attributes and modify them with greater freedom.

3rd way

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

Here you start instantiating a figure using a convenience method in the plt namespace and later you use only the object oriented interface.

It is possible to bypass the plt convenience method (matplotlib.figure.Figure) but you then have to tweak the figure for a better interactive experience (after all, it’s a convenience method).

Personal recommendations

I suggest bare plt.plot, plt.scatter in the context of an interactive session, possibly using IPython with its %matplotlib magic command, and also in the context of an exploratory Jupyter notebook.

On the other hand the object oriented approach, plus a few plt convenience methods, is the way to go

  • if you have a permanent issue to solve once for all with a customized arrangement of finely tuned subplots,
  • if you want to embed Matplotlib in the UI of a program you write.

There is a large gray area between these extremes and if you ask me what to do I’d just say “It depends”