Matplotlib: построение нескольких гистограмм в plt.subplots - PullRequest
0 голосов
/ 18 февраля 2019

Предпосылки проблемы:

Я работаю над классом , который принимает объект Axes в качестве параметра конструктора и создает(m, n) размерная фигура с гистограммой в каждой ячейке , как показано на рисунке ниже:

enter image description here

ЕстьЗдесь следует отметить две важные вещи, которые нельзя изменять каким-либо образом:

  1. Объект Figure не передается в качестве параметра конструктора;только объект Оси.Таким образом, объект subplots не может быть изменен каким-либо образом .
  2. Для параметра Axes установлено значение параметра (1,1) по умолчанию (как показано ниже)).Все модификации , необходимые для того, чтобы сделать его (m, n) цифрой , выполняются в классе (внутри его методов)
_, ax = plt.subplots() # By default takes (1,1) dimension
cm = ClassName(model, ax=ax, histogram=True) # calling my class

На чем я застрял:

Поскольку я хочу построить гистограммы в каждой ячейке, я решил подойти к ней, зацикливаясь на каждой ячейке и создавая гистограмму для каждой .

results[col].hist(ax=self.ax[y,x], bins=bins)

Однако я не могу указать оси гистограммы в любом случае.Это связано с тем, что переданный параметр Axes имеет размер по умолчанию (1,1) и, следовательно, не поддерживает индексирование .Когда я пытаюсь это сделать, я получаю сообщение TypeError.

TypeError: 'AxesSubplot' object is not subscriptable

Учитывая все это, я хотел бы знать о любых возможных способах добавления моей гистограммы к родительскому объекту Axes.Спасибо, что заглянули.

1 Ответ

0 голосов
/ 18 февраля 2019

Требование довольно строгое и, возможно, не лучший выбор дизайна.Поскольку позже вы захотите построить несколько вспомогательных сюжетов в позиции одного вложенного сюжета, этот отдельный вспомогательный сюжет создается только с единственной целью - умереть и быть замененным через несколько мгновений.

Итак, вы можете получитьположение осей, по которым вы проходите, и создайте новую сетку в этой позиции.Затем удалите исходные оси и создайте новый набор осей внутри этой вновь созданной сетки.

Ниже приведен пример.Обратите внимание, что в настоящее время требуется, чтобы оси, которые необходимо передать, имели значение 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...