matplotlib

时间:2015-06-10 11:40:41

标签: python matplotlib plot

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

  1. 一切都属于matplotlib.pyplot模块
  2. 图 - 跟踪所有子轴,一些“特殊”艺术家(标题,图例等)
  3. Axes - 具有数据空间的图像区域 - 属于图
  4. 轴 - 标记刻度线的字符串(x,y,z坐标等) - 属于Axes
  5. 艺术家 - 你可以在图上看到的一切(甚至是图,轴和轴对象) - 属于图
  6. 创建新数字的最简单方法是使用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.subplotsfig.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)

    问题:

    在此示例中,如何维护层次结构,默认情况下是创建的图形还是正在进行的操作?

1 个答案:

答案 0 :(得分:6)

问题1

我认为你已经证明了这些命令并不完全等同,只是想要一些保证。

要执行您想要执行的操作,您可以将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

问题2

数字轴等都是在封面下创建的&#39;从第一行开始plt.plotpyplot模块正在维护状态并重复使用相同的图形实例和轴实例,直到您调用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.pyplotplt.plot()函数为您提供 访问 到层次结构中由文档描述。答案是,如果你想要真正细粒度的控制,它有时并不是。这就是人们使用

的原因
fig, ax = plt.subplots()

图案或类似图案,以便他们直接拥有图形和轴对象的句柄,并可以随意操作它们。