【问题标题】:How Matplotlib Read Axes ArgumentsMatplotlib 如何读取轴参数
【发布时间】:2018-09-09 03:15:17
【问题描述】:

我来自java世界,目前为了学习matplotlib而尝试学习python。作为一个java程序员,下面的sn -p看着很奇怪。

x = np.linspace(0, 2*np.pi, 400)
y = np.sin(x**2)

f, (ax1, ax2) = plt.subplots(1, 2, sharex='all', sharey='all')
ax1.plot(x, y)
ax1.set_title('Sharing Y axis')
ax2.scatter(x, y)

plt.show()

我想知道 plt.show() 如何读取轴上设置的配置,因为我们没有向它传递任何参数。有人可以解释一下如何实现这种行为的粗略想法吗?

编辑

自从被@ImportanceOfBeingErnest 询问后,我可能会澄清我的意图。我的问题不是关于 pyplot 如何创建图像的机制,我的问题更多是关于轴配置如何对 pyplot 可见。 John Zwinck 在回答我的问题时尝试了正确的方向,我自己已经得出结论,它一定与全局状态有关。但是看一下子图的内部实现,就让我很困惑。

让我们来看看 pyplot 的一些内部实现:

def subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True,
             subplot_kw=None, gridspec_kw=None, **fig_kw):
    fig = figure(**fig_kw)
    axs = fig.subplots(nrows=nrows, ncols=ncols, sharex=sharex, sharey=sharey,
                       squeeze=squeeze, subplot_kw=subplot_kw,
                       gridspec_kw=gridspec_kw)
    return fig, axs

def subplots(self, nrows=1, ncols=1, sharex=False, sharey=False,
                 squeeze=True, subplot_kw=None, gridspec_kw=None):
            if isinstance(sharex, bool):
            sharex = "all" if sharex else "none"
        if isinstance(sharey, bool):
            sharey = "all" if sharey else "none"
        share_values = ["all", "row", "col", "none"]
        if sharex not in share_values:
            if isinstance(sharex, int):
                warnings.warn(
                    "sharex argument to subplots() was an integer. "
                    "Did you intend to use subplot() (without 's')?")

            raise ValueError("sharex [%s] must be one of %s" %
                             (sharex, share_values))
        if sharey not in share_values:
            raise ValueError("sharey [%s] must be one of %s" %
                             (sharey, share_values))
        if subplot_kw is None:
            subplot_kw = {}
        if gridspec_kw is None:
            gridspec_kw = {}

        if self.get_constrained_layout():
            gs = GridSpec(nrows, ncols, figure=self, **gridspec_kw)
        else:
            # this should turn constrained_layout off if we don't want it
            gs = GridSpec(nrows, ncols, figure=None, **gridspec_kw)

        # Create array to hold all axes.
        axarr = np.empty((nrows, ncols), dtype=object)
        for row in range(nrows):
            for col in range(ncols):
                shared_with = {"none": None, "all": axarr[0, 0],
                               "row": axarr[row, 0], "col": axarr[0, col]}
                subplot_kw["sharex"] = shared_with[sharex]
                subplot_kw["sharey"] = shared_with[sharey]
                axarr[row, col] = self.add_subplot(gs[row, col], **subplot_kw)

        # turn off redundant tick labeling
        if sharex in ["col", "all"]:
            # turn off all but the bottom row
            for ax in axarr[:-1, :].flat:
                ax.xaxis.set_tick_params(which='both',
                                         labelbottom=False, labeltop=False)
                ax.xaxis.offsetText.set_visible(False)
        if sharey in ["row", "all"]:
            # turn off all but the first column
            for ax in axarr[:, 1:].flat:
                ax.yaxis.set_tick_params(which='both',
                                         labelleft=False, labelright=False)
                ax.yaxis.offsetText.set_visible(False)

        if squeeze:
            # Discarding unneeded dimensions that equal 1.  If we only have one
            # subplot, just return it instead of a 1-element array.
            return axarr.item() if axarr.size == 1 else axarr.squeeze()
        else:
            # Returned axis array will be always 2-d, even if nrows=ncols=1.
            return axarr

据我所知,轴在这一行中被创建为一个 numpy 数组

axarr = np.empty((nrows, ncols), dtype=object)

但这是一个局部变量,并不表示在主程序上已更改的轴的状态如何对 pyplot 可见。这是我的实际问题。

【问题讨论】:

标签: python python-3.x matplotlib


【解决方案1】:

Matplotlib 的 pyplot(这是您导入为 plt 的内容)是一个奇怪的、有状态的东西,旨在模拟 Matlab。它实际上是一个全局变量(或全局变量集合的包装器,例如 plt.gca() 用于“获取当前轴”)。

很多人发现它更易于使用,但这与您对 Java 的期望完全相反。如果您愿意,完全可以在没有pyplot/plt 的情况下使用 Matplotlib,在这种情况下,对于那些来自面向对象编程背景的人来说,代码可能看起来更传统。

【讨论】:

    【解决方案2】:

    首先fig = figure(**fig_kw) 行调用pyplot.figure 函数。这会将图形注册到pyplot 状态机中。

    fig 是一个 matplotlib.figure.Figure 实例。接下来,它的subplots 方法被调用。这将实质上创建一个数组并填充matplotlib.axes.Axes 实例。这些是用self.add_subplot 创建的。

    add_subplot 将初始化坐标区并将其存储作为图窗的fig.axes 数组的一部分。

    所以总的来说,你有 pyplot 来存储图形,每个图形都将轴存储在其中。当调用plt.show() 时,它基本上会遍历所有数字并显示它们。对于每个图形,将绘制fig.axes 内的所有轴。 如果您之前通过调用它们的任何方法操作过任何轴,那么这些当然会被考虑在内,因为您操作的正是稍后也绘制的轴对象。

    【讨论】:

      猜你喜欢
      • 2020-05-19
      • 2022-06-11
      • 1970-01-01
      • 2019-11-23
      • 2012-08-31
      • 2022-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多