Подтвердить что ты не робот

Сохранение фигуры после вызова pyplot.show() приводит к пустому файлу

В следующем примере кода создается простой график, затем сохраняется его в "fig1.pdf", затем отображается и снова сохраняется в "fig2.pdf". Первое изображение выглядит, как и ожидалось, но второе пустое (содержит белый квадрат). Что на самом деле здесь происходит? Линия plt.show(), видимо, что-то напутала, но я не могу понять, что/как!

import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-1, 1, 100)
y = x**2
plt.plot(x,y)
plt.savefig('fig1.pdf')
plt.show()
plt.savefig('fig2.pdf')
4b9b3361

Ответ 1

Если вы хотите сохранить фигуру после ее отображения, вам нужно держаться за экземпляр фигуры. Причина, по которой plt.savefig не работает после вызова show, заключается в том, что текущий показатель был сброшен.

pyplot отслеживает, какие фигуры, оси и т.д. Являются "текущими" (т.е. еще не были отображены с show) за кадром. gcf и gca g и c urrent f igre и текущий a xes экземпляры соответственно. plt.savefig (и, по сути, любой другой метод pyplot) просто делает plt.gcf().savefig(...). Другими словами, получите текущий экземпляр фигуры и вызовите его метод savefig. Точно так же plt.plot в основном делает plt.gca().plot(...).

После вызова show список "текущих" фигур и осей пуст.

В общем случае лучше использовать непосредственное использование фигур и осей для построения/сохранения/показа/и т.д., А не использовать plt.plot и т.д., Чтобы неявно получить текущую фигуру/оси и построить ее. Нет ничего плохого в том, чтобы использовать pyplot для всего (особенно в интерактивном режиме), но это облегчает попадание себя в ногу.

Используйте pyplot для plt.show() и для создания фигуры и объекта (осей) осей, но затем напрямую используйте методы фигуры или осей. (например, ax.plot(x, y) вместо plt.plot(x, y) и т.д.) Основным преимуществом этого является то, что оно явное. Вы знаете, на каких объектах вы строите графики, и вам не нужно рассуждать о том, что делает конечный автомат pyplot (хотя понять интерфейс конечного автомата тоже не сложно).

В качестве примера "рекомендуемого" способа ведения дел сделайте что-то вроде:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-1, 1, 100)
y = x**2

fig, ax = plt.subplots()
ax.plot(x, y)
fig.savefig('fig1.pdf')
plt.show()
fig.savefig('fig2.pdf')

Если вы предпочитаете использовать интерфейс pyplot для всего, то просто возьмите экземпляр фигуры, прежде чем вызывать show. Например:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-1, 1, 100)
y = x**2

plt.plot(x, y)
fig = plt.gcf()
fig.savefig('fig1.pdf')
plt.show()
fig.savefig('fig2.pdf')

Ответ 2

pyplot.show блокирует и уничтожает график при закрытии. Вы можете использовать

plt.show(block=False)

после чего будет сохранено сохранение в fig2.pdf, или вы можете его распечатать еще до сохранения

plt.plot(x,y)
plt.savefig('fig2.pdf')

Ответ 3

Мне пришлось запускать plt.cla() и plt.clf() перед тем, как писать второй. Очистить текущие оси и график четкого тока, соответственно.

Ответ 4

Если вы просто хотите увидеть рисунок перед сохранением, вы можете позвонить

plt.ion()

перед построением графика, который запускает интерактивный режим, и показывает все рисунки в том виде, в котором они нарисованы. Это в основном устраняет необходимость звонить plt.show(). Вам больше не нужно закрывать цифры, чтобы продолжить.

Чтобы снова отключить интерактивный режим, позвоните в plt.ioff().