Jak powiedzieć Matplotlibowi, aby utworzył drugą (nową) fabułę, a następnie wydrukowała na starej?

147

Chcę wykreślić dane, a następnie utworzyć nową figurę i wykreślić dane2, a na koniec wrócić do pierwotnego wykresu i danych wykresu3, mniej więcej tak:

import numpy as np
import matplotlib as plt

x = arange(5)
y = np.exp(5)
plt.figure()
plt.plot(x, y)

z = np.sin(x)
plt.figure()
plt.plot(x, z)

w = np.cos(x)
plt.figure("""first figure""") # Here's the part I need
plt.plot(x, w)

Do Twojej wiadomości Jak powiedzieć matplotlib, że skończyłem z fabułą? robi coś podobnego, ale nie do końca! Nie pozwala mi uzyskać dostępu do tej oryginalnej fabuły.

Peter D.
źródło

Odpowiedzi:

152

Jeśli regularnie robisz takie rzeczy, warto zbadać zorientowany obiektowo interfejs matplotlib. W Twoim przypadku:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(5)
y = np.exp(x)
fig1, ax1 = plt.subplots()
ax1.plot(x, y)
ax1.set_title("Axis 1 title")
ax1.set_xlabel("X-label for axis 1")

z = np.sin(x)
fig2, (ax2, ax3) = plt.subplots(nrows=2, ncols=1) # two axes on figure
ax2.plot(x, z)
ax3.plot(x, -z)

w = np.cos(x)
ax1.plot(x, w) # can continue plotting on the first axis

Jest trochę bardziej szczegółowy, ale jest znacznie wyraźniejszy i łatwiejszy do śledzenia, zwłaszcza w przypadku kilku figur, z których każda ma wiele wątków pobocznych.

simonb
źródło
2
Wolę podejście zorientowane obiektowo, ponieważ gdy spodziewam się wielu cyfr, łatwiej będzie je śledzić, używając nazw, a nie liczb. Dzięki!
Peter D
1
Ale jak można zmienić etykiety i granice osi za pomocą tego podejścia. Jeśli używam ax1.ylabel, mówi, że nie znaleziono. To samo z fig1.ylabel...
George Datseris
3
@GeorgeDatseris Składnia jest trochę inna. To ax1.set_xlabel("your x label"), ax1.set_ylabel("your y label")oraz ax1.set_title("your title").
simonb
1
dlaczego użyłeś 111?
Yash Sodha
2
@yashSodha - to specyfikacja w stylu matlabowym liczby podplotów (wiersze, kolumna, indeks). Ale teraz jest znacznie łatwiejszy w użyciu plt.subplots(nrows, ncols). Zaktualizowałem przykład.
simonb
120

Kiedy dzwonisz figure, po prostu ponumeruj działkę.

x = arange(5)
y = np.exp(5)
plt.figure(0)
plt.plot(x, y)

z = np.sin(x)
plt.figure(1)
plt.plot(x, z)

w = np.cos(x)
plt.figure(0) # Here's the part I need
plt.plot(x, w)

Edycja: Zwróć uwagę, że możesz numerować wykresy w dowolny sposób (tutaj, zaczynając od 0), ale jeśli w ogóle nie podasz liczby przy tworzeniu nowej, automatyczna numeracja rozpocznie się od 1(„Styl Matlab” zgodnie z do dokumentów).

agf
źródło
3
Wydaje się, że działa to w trybie interaktywnym matplotlib, podczas gdy metoda figure () ... add_subplot () nie. Dzięki!
chbrown
@SebMa Proszę nie zmieniać kodu bez zrozumienia go. Ta odpowiedź dotyczyła w szczególności przekazywania numeru figure, który usunąłeś. Pozostałe rzeczy, które zmieniłeś, zostały skopiowane z oryginalnego postu, a nie pomyłki w mojej odpowiedzi.
agf
@agf Cześć, usunąłem 1wnętrze, plt.figure(1)ponieważ myślałem, że liczba jest automatycznie zwiększana i dlatego nie jest konieczna. Przepraszam.
SebMa
18

Jednak numeracja zaczyna się od 1, więc:

x = arange(5)
y = np.exp(5)
plt.figure(1)
plt.plot(x, y)

z = np.sin(x)
plt.figure(2)
plt.plot(x, z)

w = np.cos(x)
plt.figure(1) # Here's the part I need, but numbering starts at 1!
plt.plot(x, w)

Ponadto, jeśli masz wiele osi na figurze, na przykład na wykresach podrzędnych, użyj axes(h)polecenia gdzie hjest uchwyt żądanego obiektu osi, aby skupić się na tych osiach.

(nie mam jeszcze uprawnień do komentowania, przepraszam za nową odpowiedź!)

Ross B.
źródło
10
0działa, numeracja automatyczna zaczyna się od 1, jeśli w ogóle jej nie podasz.
agf
0

Jednym ze sposobów, które znalazłem po pewnych zmaganiach, jest utworzenie funkcji, która pobiera macierz data_plot, nazwę pliku i kolejność jako parametr, aby utworzyć wykresy pudełkowe z podanych danych w uporządkowanej figurze (różne zamówienia = różne figury) i zapisać je pod podaną nazwą pliku.

def plotFigure(data_plot,file_name,order):
    fig = plt.figure(order, figsize=(9, 6))
    ax = fig.add_subplot(111)
    bp = ax.boxplot(data_plot)
    fig.savefig(file_name, bbox_inches='tight')
    plt.close()
emir
źródło