简体   繁体   中英

Matplotlib multiple lines on graph

I've been having an issue with saving matplotlib graphs as images. The images are saving differently from what shows up when I call the .show() method on the graph. An example is here: http://s1.postimg.org/lbyei5cfz/blue5.png

I'm not sure what else to do. I've spent the past hours trying to figure out what's causing it, but I can't figure it out.

Here is my code in it's entirety.

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

Sorry if this is a stupid mistake I'm making, I just find it peculiar how plt.show() and plt.savefig are different.

Thanks for the help.

As stated correctly by David, plt.show() resets current figure. plt.savefig() , however, does not, so you need to reset it explicitly. plt.clf() or plt.figure() are two functions that can do it dor you. Just insert the call right after plt.savefig :

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

If you want to save the figure after displaying it, you'll need to hold on to the figure instance. The reason that plt.savefig doesn't work after calling show is that the current figure has been reset.

pyplot keeps track of which figures, axes, etc are "current" (ie have not yet been displayed with show ) behind-the-scenes. gcf and gca get the current figure and current axes instances, respectively. plt.savefig (and essentially any other pyplot method) just does plt.gcf().savefig(...) . In other words, get the current figure instance and call its savefig method. Similarly plt.plot basically does plt.gca().plot(...) .

After show is called, the list of "current" figures and axes is empty.

In general, you're better off directly using the figure and axes instances to plot/save/show/etc, rather than using plt.plot , etc, to implicitly get the current figure/axes and plot on it. There's nothing wrong with using pyplot for everything (especially interactively), but it makes it easier to shoot yourself in the foot.

Use pyplot for plt.show() and to generate a figure and an axes object(s), but then use the figure or axes methods directly. (eg ax.plot(x, y) instead of plt.plot(x, y) , etc) The main advantage of this is that it's explicit. You know what objects you're plotting on, and don't have to reason about what the pyplot state-machine does (though it's not that hard to understand the state-machine interface, either).

As an example of the "recommended" way of doing things, do something like:

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')

If you'd rather use the pyplot interface for everything, then just grab the figure instance before you call show . For example:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM