1

How do pyplot functions such as show() and savefig() not require a "plot object" to work?

For example, the following code works, but somehow I expect to use a file handler or pass a "plot object" into plt.show() and plot.savefig("venn3.pdf").

from matplotlib import pyplot as plt
from matplotlib_venn import venn3, venn3_circles

# Subset sizes
s = (2,3,4,3,1,0.5,4)

v = venn3(subsets=s, set_labels=('A', 'B', 'C'))

# Subset labels
v.get_label_by_id('100').set_text('Abc')
v.get_label_by_id('010').set_text('aBc')
v.get_label_by_id('110').set_text('ABc')
v.get_label_by_id('001').set_text('Abc')
v.get_label_by_id('101').set_text('aBc')
v.get_label_by_id('011').set_text('ABc')
v.get_label_by_id('111').set_text('ABC')

# Subset colors
v.get_patch_by_id('100').set_color('c')
v.get_patch_by_id('010').set_color('#993333')
v.get_patch_by_id('110').set_color('blue')

# Subset alphas
v.get_patch_by_id('101').set_alpha(0.4)
v.get_patch_by_id('011').set_alpha(1.0)
v.get_patch_by_id('111').set_alpha(0.7)

# Border styles
c = venn3_circles(subsets=s, linestyle='solid')
c[0].set_ls('dotted')  # Line style
c[1].set_ls('dashed')
c[2].set_lw(1.0)       # Line width

plt.show() # For show() to work without using variable v seems counter-intuitive to me.
plt.savefig("venn3.pdf") # For savefig() to work without using variable v seems counter-intuitive to me.

2[]

Sean
  • 713
  • 1
  • 10
  • 28

2 Answers2

1

Pyplot uses a global variable to hold the figure object. All pyplot functions work with that variable(s). If you are working interactively, pyplot is perfectly fine since only you will modify that variable. If you are writing multi-threaded or multi-user code pyplot will not work, and you would have to use the layer benath it, which needs the figure object passed in (and is a terrible interface).

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
Christian Sauer
  • 10,351
  • 10
  • 53
  • 85
  • @RoryDaulton no, it was not. To expand: Imagine a webserver which draws pictures on demand - there could be multiple users trying to call /draw at the same time. If your webserver user threading, pyplot will have very funny errors. – Christian Sauer Jun 06 '17 at 09:59
  • [Here](https://stackoverflow.com/a/43572382/4124317) would be an example for multiprocessing using pyplot, which works fine. I also don't think the matplotlib API is terrible. It is one of the best documented API I know, it is easy to use, and it is completely object-oriented. There is nothing preventing one to use it, if needed. – ImportanceOfBeingErnest Jun 06 '17 at 10:40
  • @ImportanceOfBeingErnest That's multiprocessing (as in: every request runs in it's own request). Multithreading can be done (flask dev server as an example) and that won't work, since the state is shared. – Christian Sauer Jun 06 '17 at 13:20
1

matplotlib.pyplot is often called "statemachine". This means that the function it provides do certain things depending on the internal state of pyplot.

In your code, you have created a figure and this is stored as an object; pyplot knows it has one figure.

If you then call other commands, it is assumend that they apply to that one figure which has been created previously, like plt.savefig.

plt.show() would work on all previously created figures (all of them would be shown).

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712