python - matplotlib 中的层次结构

标签 python matplotlib plot

根据 this文章中,matplotlib 中的所有内容都是按层次结构组织的。在层次结构的顶部是 matplotlib“状态机环境”,它由 matplotlib.pyplot 模块提供。在这个级别,简单的函数用于将绘图元素(线条、图像、文本等)添加到当前图形中的当前轴。层次结构中的下一层是面向对象接口(interface)的第一层,其中 pyplot 仅用于图形创建等少数功能,用户明确创建并跟踪图和轴对象。在此级别,用户使用 pyplot 创建图形,并通过这些图形可以创建一个或多个轴对象。然后,这些轴对象将用于大多数绘图操作。 还有其他术语,如 Figure、Axes、Axis、Artist(在提到的页面上有一张很好的图片解释了所有这些)。总结:

  1. 一切都属于matplotlib.pyplot模块
  2. 图形 - 跟踪所有子 Axes,一些“特殊”艺术家(标题、图形图例等)
  3. 轴 - 具有数据空间的图像区域 - 属于图
  4. Axis - 标记刻度的字符串(x、y、z 坐标等)- 属于 Axes
  5. 艺术家 - 您在图中看到的一切(甚至是图、轴和轴对象)- 属于图

创建新图形的最简单方法是使用 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)

问题:

此示例中的层次结构是如何维护的,Figure 是默认创建的还是发生了什么?

最佳答案

问题一

我认为您已经证明这些命令并不完全等同,只是想对此有所保证。

做你想做的事 - 你可以将 projection 传递给 add_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 .

问题2

图形轴等都是由 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()

模式或类似的东西,这样他们就可以直接处理图形和坐标轴对象,并可以随意操纵它们。

关于python - matplotlib 中的层次结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30755249/

相关文章:

r - 绘制光栅文件

algorithm - 给定一组 X-Y 坐标,用于插入缺失数据点的好算法是什么?

python - 为什么某些 mysql 连接在删除 + 插入后选择 mysql 数据库中的旧数据?

python - 我正在尝试制作一个液晶显示屏程序,以便所有数字都并排打印,但它不起作用

python - pickle 多个字典

python - 一张图片上的多个图表(python)

python - 检查脚本事件的代码 (python)

python - 有条件地改变特定单元格的背景颜色

python - matplotlib 路径线宽连接到图形缩放

python - 箱线图 X 值出现多次