1

So I tried to write a custom plotting function, which will behave like plot, in that you can call subplot and then calls to new_plot will be directed to that subplot, subsequent calls will plot over top of the original plot in different colors, etc.

However, when I try to plot multiple times from the interactive prompt in IPython, only the first call works. If I call multiple times in a script or in a single command, it works.

I've stripped out everything except the bare minimum that demonstrates the problem:

import matplotlib.pyplot as plt
from numpy.random import randn


def new_plot():
    # get a figure/plot
    ax = plt.gca()

    # Plot the poles and set marker properties
    ax.plot(randn(10), randn(10))


if __name__ == "__main__":
    plt.subplot(2, 1, 1)
    new_plot()
    new_plot()
    plt.subplot(2, 1, 2)
    new_plot()
    new_plot()
    plt.show()

Running this script works fine, producing 2 plots of different colors on top of each other in each subplot. Also, calling the function twice in one line of IPython interactive prompt works fine:

In [3]: new_plot()
   ...: new_plot()
   ...: 

However, calling the function twice in a row does not work, only the first call succeeds, the rest fail silently:

In [4]: new_plot()

In [5]: new_plot()

Whyyyyyyyyyyyyyyyyy?

endolith
  • 25,479
  • 34
  • 128
  • 192

1 Answers1

1

You are running into problems because you are combining the object oriented interface for Matplotlib with Pyplot, the state-machine environment. More information here. This question is also helpful.

You can make your example work by using Pyplot in new_plot():

def new_plot():
    # Pyplot plot function
    plt.plot(randn(10), randn(10))

or by calling draw() from IPython interactive prompt after the calls to new_plot().

Pyplot functions (plt.plot in this case) automatically redraw the figure but methods of the object oriented interface (ax.plot) do not.

Community
  • 1
  • 1
Molly
  • 13,240
  • 4
  • 44
  • 45
  • but `pyplot.plot()`'s source code starts with `ax = gca()`. so I should not try to copy that behavior? – endolith Jul 10 '14 at 20:48
  • No in general, I don't think you should copy that behavior. pyplot.plot() updates the figure with a call to draw_if_interactive which is not intended to be used outside of pyplot. – Molly Jul 10 '14 at 21:38
  • ok, is there a way to add patches without an `ax` object then? I was basing on things like http://stackoverflow.com/a/10665448/125507 http://stackoverflow.com/questions/13831549/get-matplotlib-color-cycle-state#comment19037056_13831816 – endolith Jul 12 '14 at 01:09
  • calling `plt.draw()` at the end of the function seems to work. anything wrong with that? – endolith Jul 12 '14 at 01:21