根据this文章,matplotlib
中的所有内容都按层次结构进行组织。在层次结构的顶部是matplotlib
“状态机环境”,它由matplotlib.pyplot
模块提供。在此级别,简单函数用于将绘图元素(线条,图像,文本等)添加到当前图形中的当前轴。层次结构中的下一级是面向对象的接口的第一级,其中pyplot
仅用于少数功能,如图形创建,用户显式创建并跟踪图形和轴对象。在此级别,用户使用pyplot
来创建图形,通过这些图形,可以创建一个或多个轴对象。然后,这些轴对象用于大多数绘图操作。
还有其他术语,如图,轴,轴,艺术家(有很好的图片解释了所有这些,在提到的页面上)。总结:
matplotlib.pyplot
模块创建新数字的最简单方法是使用pyplot:
fig = plt.figure() # an empty figure with no axes
fig, ax_lst = plt.subplots(2, 2) # a figure with a 2x2 grid of Axes
我经常看到这两种方法可以互换使用,我希望它们基本上是等价的。但是,使用fig, ax = plt.subplots()
和fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
获得相同的结果
以下是我的实验,plt.figure()
:
In [1]: from mpl_toolkits.mplot3d import Axes3D
In [2]: import matplotlib.pyplot as plt
In [3]: fig = plt.figure()
In [4]: ax = fig.add_subplot(111, projection='3d')
In [5]: fig
Out[5]: <matplotlib.figure.Figure at 0x7f8377ca0610>
In [6]: ax
Out[6]: <matplotlib.axes._subplots.Axes3DSubplot at 0x7f8377bfb310>
In [7]:
以下是我的实验,plt.subplots()
:
In [1]: from mpl_toolkits.mplot3d import Axes3D
In [2]: import matplotlib.pyplot as plt
In [3]: fig, ax = plt.subplots()
In [4]: fig
Out[4]: <matplotlib.figure.Figure at 0x7f3dcf96e710>
In [5]: ax
Out[5]: <matplotlib.axes._subplots.AxesSubplot at 0x7f3dced564d0>
In [6]:
如您所见,第一个创建matplotlib.axes._subplots.Axes3DSubplot
对象,而第二个创建matplotlib.axes._subplots.AxesSubplot
对象。我一直在help(plt.subplots)
搜索projection
关键字,但我找不到任何内容。所以我试图为plt.subplots
和fig.add_subplot
使用相同的参数但是我收到以下错误:
In [7]: fig, ax = plt.subplots(111, projection='3d')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-a905adad48f5> in <module>()
----> 1 fig, ax = plt.subplots(111, projection='3d')
/usr/lib/python2.7/dist-packages/matplotlib/pyplot.pyc in subplots(nrows, ncols, sharex, sharey, squeeze, subplot_kw, gridspec_kw, **fig_kw)
1076 gridspec_kw = {}
1077
-> 1078 fig = figure(**fig_kw)
1079 gs = GridSpec(nrows, ncols, **gridspec_kw)
1080
/usr/lib/python2.7/dist-packages/matplotlib/pyplot.pyc in figure(num, figsize, dpi, facecolor, edgecolor, frameon, FigureClass, **kwargs)
433 frameon=frameon,
434 FigureClass=FigureClass,
--> 435 **kwargs)
436
437 if figLabel:
/usr/lib/python2.7/dist-packages/matplotlib/backends/backend_tkagg.pyc in new_figure_manager(num, *args, **kwargs)
78 """
79 FigureClass = kwargs.pop('FigureClass', Figure)
---> 80 figure = FigureClass(*args, **kwargs)
81 return new_figure_manager_given_figure(num, figure)
82
TypeError: __init__() got an unexpected keyword argument 'projection'
问题:
是fig, ax = plt.subplots()
和fig = plt.figure(); ax = fig.add_subplot(111, projection='3d')
等价物,如果是,我如何在我的示例中使用fig, ax = plt.subplots()
?
在提到的页面上还有以下代码:
#!/bin/env python
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2, 100)
# The first call to plt.plot will automatically create the necessary figure and axes to achieve the desired plot.
plt.plot(x, x, label='linear')
# Subsequent calls to plt.plot re-use the current axes and each add another line.
plt.plot(x, x**2, label='quadratic')
plt.plot(x, x**3, label='cubic')
# Setting the title, legend, and axis labels also automatically use the current axes and set the title, create the legend, and label the axis respectively.
plt.xlabel('x label')
plt.ylabel('y label')
plt.title("Simple Plot")
plt.legend()
plt.show()
正如您所看到的,没有此类功能fig = plt.figure()
或fig, ax_lst = plt.subplots(2, 2)
问题:
在此示例中,如何维护层次结构,默认情况下是创建的图形还是正在进行的操作?
答案 0 :(得分:6)
我认为你已经证明了这些命令并不完全等同,只是想要一些保证。
要执行您想要执行的操作,您可以将projection
传递给所使用的add_subplot()
来电。通过设置一个subplot参数字典并将其传递给例如
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
subplot_args = {'projection':'3d'}
fig, ax = plt.subplots(subplot_kw=subplot_args)
使用命名参数subplot_kw
描述in the docs here。
数字轴等都是在封面下创建的&#39;从第一行开始plt.plot
。 pyplot
模块正在维护状态并重复使用相同的图形实例和轴实例,直到您调用plt.show()
。
注意 - 就目前而言,您无法处理这些实例。如果你想要,你可以随时获得一个句柄。通过调用
fig = plt.gcf()
和
ax = plt.gca()
其中gcf()
and gca()
分别获取当前数字和获取当前轴。这是基于Matplotlib最初基于matlab功能的模型。
如果您真的非常想知道自动创建是如何完成的 - 它都是开源的。通过调用the code here中的plot()
,您可以看到对gca()
的调用创建了一个Axes实例。这反过来calls gcf()
,looks for a FigureManager
(实际上维持状态)。如果存在,则返回它正在管理的数字,否则使用plt.figure()
创建一个新数字。同样,这个过程在某种程度上继承自matlab,在任何绘图操作之前,初始调用通常是figure
。
我认为您可能正在推动的是如何使用matplotlib.pyplot
等plt.plot()
函数为您提供 访问 到层次结构中由文档描述。答案是,如果你想要真正细粒度的控制,它有时并不是。这就是人们使用
fig, ax = plt.subplots()
图案或类似图案,以便他们直接拥有图形和轴对象的句柄,并可以随意操作它们。