matplotlib: czy mogę tworzyć obiekty AxesSubplot, a następnie dodawać je do instancji Figure?

Patrząc na dokumentację matplotlib, wydaje się, że standardowym sposobem dodawania AxesSubplot do Figure jest użycie Figure.add_subplot:

from matplotlib import pyplot

fig = pyplot.figure()
ax = fig.add_subplot(1,1,1)
ax.hist( some params .... )

Chciałbym móc tworzyć AxesSubPlot - podobne obiekty niezależnie od figury, więc mogę z nich korzystać w różnych figurach. Coś jak

fig = pyplot.figure()
histoA = some_axes_subplot_maker.hist( some params ..... )
histoA = some_axes_subplot_maker.hist( some other params ..... )
# make one figure with both plots
fig.add_subaxes(histo1, 211)
fig.add_subaxes(histo1, 212)
fig2 = pyplot.figure()
# make a figure with the first plot only
fig2.add_subaxes(histo1, 111)

Czy jest to możliwe w matplotlib, a jeśli tak, to jak Mogę to zrobić?

Update: nie udało mi się oddzielić tworzenia osi i figur, ale następujące przykłady w odpowiedziach poniżej, można łatwo ponownie użyj wcześniej utworzonych osi w nowych lub olf figure instances. Można to zilustrować za pomocą prostej funkcji:

def plot_axes(ax, fig=None, geometry=(1,1,1)):
    if fig is None:
        fig = plt.figure()
    if ax.get_geometry() != geometry :
        ax.change_geometry(*geometry)
    ax = fig.axes.append(ax)
    return fig
Author: juanchopanza, 2011-06-10

3 answers

Zazwyczaj po prostu przekazujesz instancję axes do funkcji.

Na przykład:

import matplotlib.pyplot as plt
import numpy as np

def main():
    x = np.linspace(0, 6 * np.pi, 100)

    fig1, (ax1, ax2) = plt.subplots(nrows=2)
    plot(x, np.sin(x), ax1)
    plot(x, np.random.random(100), ax2)

    fig2 = plt.figure()
    plot(x, np.cos(x))

    plt.show()

def plot(x, y, ax=None):
    if ax is None:
        ax = plt.gca()
    line, = ax.plot(x, y, 'go')
    ax.set_ylabel('Yabba dabba do!')
    return line

if __name__ == '__main__':
    main()

Aby odpowiedzieć na twoje pytanie, zawsze możesz zrobić coś takiego:

def subplot(data, fig=None, index=111):
    if fig is None:
        fig = plt.figure()
    ax = fig.add_subplot(index)
    ax.plot(data)

Można również po prostu dodać instancję osi do innej figury:

import matplotlib.pyplot as plt

fig1, ax = plt.subplots()
ax.plot(range(10))

fig2 = plt.figure()
fig2.axes.append(ax)

plt.show()

Zmiana rozmiaru w celu dopasowania innych "kształtów" jest również możliwa, ale szybko stanie się to bardziej kłopotliwe niż jest warte. Podejście po prostu przekazywanie wokół rysunku lub osi instancji (lub listy instancji) jest znacznie z doświadczenia wiem, że to prostsze w skomplikowanych sprawach...

 24
Author: Joe Kington,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-29 07:25:51

Dla wykresów liniowych, możesz sobie poradzić z Line2D obiektami:

fig1 = pylab.figure()
ax1 = fig1.add_subplot(111)
lines = ax1.plot(scipy.randn(10))

fig2 = pylab.figure()
ax2 = fig2.add_subplot(111)
ax2.add_line(lines[0])
 5
Author: Steve Tjoa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-10 17:58:23

Poniżej przedstawiono jak "przenieść" osie z jednej figury do drugiej. Jest to zamierzona funkcjonalność ostatniego przykładu, który w nowszych wersjach matplotlib już nie działa, ponieważ osie nie mogą żyć w kilku figurach na raz.

Najpierw musisz usunąć osie z pierwszej figury, a następnie dołączyć ją do następnej figury i nadać jej pewną pozycję do życia.

import matplotlib.pyplot as plt

fig1, ax = plt.subplots()
ax.plot(range(10))
ax.remove()

fig2 = plt.figure()
ax.figure=fig2
fig2.axes.append(ax)
fig2.add_axes(ax)

dummy = fig2.add_subplot(111)
ax.set_position(dummy.get_position())
dummy.remove()
plt.close(fig1)

plt.show()
 5
Author: ImportanceOfBeingErnest,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-24 11:16:44