0

from Is there a way of drawing a caption box in matplotlib

from matplotlib import pyplot as plt
import numpy as np

x = np.arange(0,3,.25)
y = np.sin(x)
txt = '''
    Lorem ipsum dolor sit amet, consectetur adipisicing elit,
    sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
    Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris
    nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
    reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
    pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
    culpa qui officia deserunt mollit anim id est laborum.'''

fig = plt.figure()
ax1 = fig.add_axes((.1,.4,.8,.5))
ax1.bar(x,y,.2)
fig.text(.1,.1,txt) #<-doesn't work interactively
#plt.show()

This code works if I run it as a script. But if I first run everything up to, but not including the fig.text line, then I input the fig.text line into the console, the txt doesn't show up in the figure! Why?

Community
  • 1
  • 1
Majid alDosari
  • 133
  • 1
  • 2
  • 13
  • It's probably getting clipped, but I don't understand how. I see it fine in an inline figure in an IPython notebook – Paul H Jan 31 '15 at 02:52
  • oh never mind. all i had to do was resize the figure window with my mouse and it magically showed up. still, i shouldn't have to do this. BUG?? – Majid alDosari Jan 31 '15 at 02:53

2 Answers2

2

This is a feature, not a bug.

Redrawing the figure can be very computationally expensive so the OO interface does not force a re-draw of the figure. By deferring the expense of drawing you can greatly improve the performance of functions that make many calls to Figure and Axes methods. To get the figure on the screen to update to reflect the state of the you need to explicitly update it. You programmaticly force a re-draw via

fig.canvas.draw()

or

plt.draw()

which will redraw the 'current figure'. Resizing the window will cause the GUI framework to re-draw it's window which in turn triggers a full re-draw of the mpl figur.

When you use the pyplot functions (rather than the OO interface) a redraw is forced on every plotting command. This difference is because the pyplot interface is coupled with a state-machine (that keeps track of your current figure/axes) and was designed for interactive use, where as the OO interface (which the pyplot interface is built on top of) is designed for programmatic usage.

This is an annoyance that the devs are aware of and making this behave a bit more intuitively is on the near/mid term road map (see https://github.com/matplotlib/matplotlib/pull/3587 and the links there in).

tacaswell
  • 84,579
  • 22
  • 210
  • 199
  • accepted..but can you explain the behavior i noticed that i commented about in MattDMo's answer? – Majid alDosari Feb 02 '15 at 16:45
  • It is because of the way the event loop works. When you do it all in one line both commands (`runfile` and `fig.text`) run before control is returned to the event loop which is when the window _actually_ gets created (from the PoV of the gui frame work, before that the events to do the creation and display were just on the event stack) so the first draw of the window includes the artist from the `text` call so it shows up. – tacaswell Feb 02 '15 at 19:48
-1

Read through this information on interactive mode in matplotlib. It either needs to be turned on by default in your matplotlibrc file, set via matplotlib.interactive(), or turned on in your console by running plt.ion(), which is what I'd recommend here. In the long term, though, using a customized matplotlibrc file is your best bet.

MattDMo
  • 100,794
  • 21
  • 241
  • 231
  • interactivity is not the problem. the plot shows up but without the text. if i comment out the `fig.text`, then at the prompt: `runfile('thescript.py');fig.text(....` works! but if i `runfile` then i type `fig.text` at the prompt, it doesn't work! – Majid alDosari Jan 31 '15 at 02:43