Ответ
Да, это нормальное ожидаемое поведение для фигур matplotlib.
Объяснение
Когда вы запускаете plt.plot(...)
, вы создаете с одной стороныlines
экземпляр фактического сюжета:
>>> print( plt.plot(year, pop) )
[<matplotlib.lines.Line2D object at 0x000000000D8FDB00>]
... и с другой стороны, экземпляр Figure
, который устанавливается как «текущая фигура» и доступен через plt.gcf()
(сокращение от«получить текущую фигуру»):
>>> print( plt.gcf() )
Figure(432x288)
Линии (а также другие элементы графика, которые вы можете добавить) все размещаются на текущей фигуре.Когда вызывается plt.show()
, текущее значение отображается , а затем очищается (!) , поэтому второй вызов plt.show()
ничего не отображает.
Стандартный обходной путь
Одним из способов решения этой проблемы является явное сохранение текущего экземпляра Figure
и последующее его непосредственное отображение с помощью fig.show()
, например:
plt.plot(year, pop)
fig = plt.gcf() # Grabs the current figure
plt.show() # Shows plot
plt.show() # Does nothing
fig.show() # Shows plot again
fig.show() # Shows plot again...
А чащеИспользуемая альтернатива заключается в явной инициализации текущей фигуры в начале, до каких-либо команд построения.
fig = plt.figure() # Initializes current figure
plt.plot(year, pop) # Adds to current figure
plt.show() # Shows plot
fig.show() # Shows plot again
Это часто сочетается со спецификацией некоторых дополнительных параметров фигуры, например:
fig = plt.figure(figsize=(8,8))
Для пользователей ноутбуков Jupyter
Подход fig.show()
может не работать в контексте ноутбуков Jupyter и вместо этого может выдавать следующее предупреждение и не отображать сюжет:
C: \ redacted \ path \ lib \ site-packages \ matplotlib \ figure.py: 459: UserWarning: matplotlib в настоящее время использует не-GUI бэкэнд, поэтому не может отобразить рисунок
FortuВ действительности, просто запись fig
в конце ячейки кода (вместо fig.show()
) подтолкнет цифру к выводу ячейки и все равно отобразит ее.Если вам нужно отобразить его несколько раз из одной и той же кодовой ячейки, вы можете добиться того же эффекта, используя функцию display
:
fig = plt.figure() # Initializes current figure
plt.plot(year, pop) # Adds to current figure
plt.show() # Shows plot
plt.show() # Does nothing
from IPython.display import display
display(fig) # Shows plot again
display(fig) # Shows plot again...
Использование функций
Одна из причин, по которой вам нужно многократно набирать show
, состоит в том, чтобы каждый раз вносить различные изменения.Это можно сделать с помощью подхода fig
, рассмотренного выше, но для более подробных определений графика часто проще просто заключить базовую фигуру в функцию и вызывать ее повторно.
Пример:
def my_plot(year, pop):
plt.plot(year, pop)
plt.xlabel("year")
plt.ylabel("population")
my_plot(year, pop)
plt.show() # Shows plot
my_plot(year, pop)
plt.show() # Shows plot again
my_plot(year, pop)
plt.title("demographics plot")
plt.show() # Shows plot again, this time with title