Matplotlib:绘制多个直方图plt.子批次

2024-04-30 02:26:38 发布

您现在位置:Python中文网/ 问答频道 /正文

问题背景:

我正在研究一个类,它将一个轴对象作为构造函数参数并生成一个(m,n)维图形,每个单元格中都有一个直方图,类似下图:

enter image description here

这里有两件重要的事要注意,我不能以任何方式修改:

  1. Figure对象不作为构造函数参数传递;只有axis对象被传递。因此,子批次对象不能以任何方式修改。在
  2. 默认情况下,轴参数设置为(1,1)图形的参数(如下所示)。使其成为(m,n)图所需的所有修改都在类内执行(在其方法内)
_, ax = plt.subplots() # By default takes (1,1) dimension
cm = ClassName(model, ax=ax, histogram=True) # calling my class

我所坚持的:

因为我想在每个单元格内绘制直方图,所以我决定通过在每个单元格上循环并为每个单元格创建一个直方图来接近它。在

^{pr2}$

但是,我不能以任何方式指定直方图的轴。这是因为传递的轴参数是默认维度(1,1),因此不可索引。当我尝试这个时,我得到一个打字错误说。在

TypeError: 'AxesSubplot' object is not subscriptable

考虑到所有这些,我想知道任何可能的方法,我可以把我的直方图添加到父轴对象。谢谢你看。在


Tags: 对象方法图形参数方式情况plt函数参数
1条回答
网友
1楼 · 发布于 2024-04-30 02:26:38

这个要求非常严格,也许不是最好的设计选择。因为您以后想在一个子图的位置绘制多个子图,所以创建这个子图的唯一目的是在几分钟后死亡并被替换。在

因此,您可以获得传入轴的位置,并在该位置创建一个新的gridspec。然后删除原始轴,并在新创建的gridspec中创建一组新轴。在

下面就是一个例子。注意,它当前要求传入的轴是Subplot(与任何轴相反)。 它还将绘图的数量硬编码为2*2。在实际的用例中,您可能会从传入的model中获得该数字。在

import matplotlib.pyplot as plt
import numpy as np
from matplotlib import gridspec

class ClassName():
    def __init__(self, model, ax=None, **kwargs):
        ax = ax or plt.gca()
        if not hasattr(ax, "get_gridspec"):
            raise ValueError("Axes needs to be a subplot")
        parentgs = ax.get_gridspec()
        q = ax.get_geometry()[-1]

        # Geometry of subplots
        m, n = 2, 2
        gs = gridspec.GridSpecFromSubplotSpec(m,n, subplot_spec=parentgs[q-1])
        fig = ax.figure
        ax.remove()

        self.axes = np.empty((m,n), dtype=object)
        for i in range(m):
            for j in range(n):
                self.axes[i,j] = fig.add_subplot(gs[i,j], label=f"{i}{j}")


    def plot(self, data):
        for ax,d in zip(self.axes.flat, data):
            ax.plot(d)


_, (ax,ax2) = plt.subplots(ncols=2) 
cm = ClassName("mymodel", ax=ax2) # calling my class
cm.plot(np.random.rand(4,10))

plt.show()

enter image description here

相关问题 更多 >