2014-11-27 4 views
1

У меня возникла проблема с сохранением графиков matplotlib как изображений. Изображения сохраняются иначе, чем отображаются, когда я вызываю метод .show() на графике. Пример: http://s1.postimg.org/lbyei5cfz/blue5.pngMatplotlib несколько строк на графике

Я не уверен, что еще делать. Я провел последние часы, пытаясь понять, что вызывает это, но я не могу понять это.

Вот мой код целиком.

import matplotlib.pyplot as plt 
import random 
turn = 1 #for the x values 
class Graph(): 
    def __init__(self, name, color): 
     self.currentValue = 5 #for the y values 
     self.x = [turn] 
     self.y = [self.currentValue] 
     self.name = name 
     self.color = color 

    def update(self): 
     if random.randint(0,1): #just to show if the graph's value goes up or down 
      self.currentValue += random.randint(0,10) 
      self.y.append(self.currentValue) 
     else: 
      self.currentValue -= random.randint(0,10) 
      self.y.append(self.currentValue) 
     self.x.append(turn) 

    def plot(self): 
     lines = plt.plot(self.x,self.y) 
     plt.setp(lines, 'color',self.color) 
     plt.savefig(self.name + str(turn)) 
     #plt.show() will have a different result from plt.savefig(args) 

graphs = [Graph("red",'r'),Graph("blue",'b'),Graph("green",'g')] 
for i in range(5): 
    for i in graphs: 
     i.update() #changes the x and y value 
     i.plot() #saves the picture of the graph 
    turn += 1 

Извините, если это глупая ошибка, которую я делаю, я просто нахожу это свойственно, как plt.show() и plt.savefig различны.

Спасибо за помощь.

ответ

2

Как было указано правильно Давида, plt.show() сбрасывает текущий показатель. plt.savefig(), однако, нет, поэтому вам нужно его сбросить явно. plt.clf() или plt.figure() - две функции, которые могут сделать это до вас.Просто вставьте вызов сразу после plt.savefig:

plt.savefig(self.name + str(turn)) 
    plt.clf() 
1

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

pyplot отслеживает, какие фигуры, оси и т. Д. Являются «текущими» (т. Е. Еще не отображаются с show) за кадром. gcf и gca получить текущие экземпляры токовых и токовых осей соответственно. plt.savefig (и практически любой другой pyplot способ) только plt.gcf().savefig(...). Другими словами, получите текущий экземпляр фигуры и вызовите его метод savefig. Аналогично plt.plot в основном делает plt.gca().plot(...).

После того, как вызывается show, список «текущих» цифр и осей пуст.

В общем, вам лучше использовать фигуры и оси для создания/сохранения/отображения/etc, вместо того, чтобы использовать 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') 

source

+0

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

+0

Спасибо за помощь. Следует, однако, отметить, что, выполняя метод, который вы мне показали, DID работает, однако он использовал огромное количество оперативной памяти. (Почти 1 Гб за то, что я делал). Проще говоря, plt.clf(), чтобы очистить график, было намного более эффективным. – user3780831

Смежные вопросы