Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b58afd4

Browse files
committed
Update FAQ re: batch/webserver use.
The previous FAQ entry re: not having a window appear is far too complicated (in practice, just not calling show() is good enough, especially now that we'll select a noninteractive backend when working headlessly anyways. The previous FAQ entry re: webserver use is also far too complicated; again the choice of backend is now automatic, and we don't need to select a priori what kind of output will be used (Matplotlib will switch the underlying backend automatically).
1 parent 9e7650e commit b58afd4

1 file changed

Lines changed: 39 additions & 67 deletions

File tree

doc/faq/howto_faq.rst

Lines changed: 39 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -423,18 +423,12 @@ locators as desired because the two axes are independent.
423423
Generate images without having a window appear
424424
----------------------------------------------
425425

426-
The easiest way to do this is use a non-interactive backend (see
427-
:ref:`what-is-a-backend`) such as Agg (for PNGs), PDF, SVG or PS. In
428-
your figure-generating script, just call the
429-
:func:`matplotlib.use` directive before importing pylab or
430-
pyplot::
431-
432-
import matplotlib
433-
matplotlib.use('Agg')
434-
import matplotlib.pyplot as plt
435-
plt.plot([1,2,3])
436-
plt.savefig('myfig')
426+
Simply do not call `~matplotlib.pyplot.show`, and directly save the figure to
427+
the desired format::
437428

429+
import matplotlib.pyplot as plt
430+
plt.plot([1, 2, 3])
431+
plt.savefig('myfig.png')
438432

439433
.. seealso::
440434

@@ -454,7 +448,7 @@ the mainloop. Because this mainloop is blocking by default (i.e., script
454448
execution is paused), you should only call this once per script, at the end.
455449
Script execution is resumed after the last window is closed. Therefore, if
456450
you are using Matplotlib to generate only images and do not want a user
457-
interface window, you do not need to call ``show`` (see :ref:`howto-batch`
451+
interface window, you do not need to call ``show`` (see :ref:`howto-batch`
458452
and :ref:`what-is-a-backend`).
459453

460454
.. note::
@@ -629,66 +623,44 @@ Looking for something to do? Search for `TODO <../search.html?q=todo>`_
629623
or look at the open issues on github.
630624

631625

632-
633-
634626
.. _howto-webapp:
635627

636628
Matplotlib in a web application server
637629
======================================
638630

639-
Many users report initial problems trying to use Matplotlib in web
640-
application servers, because by default Matplotlib ships configured to
641-
work with a graphical user interface which may require an X11
642-
connection. Since many barebones application servers do not have X11
643-
enabled, you may get errors if you don't configure Matplotlib for use
644-
in these environments. Most importantly, you need to decide what
645-
kinds of images you want to generate (PNG, PDF, SVG) and configure the
646-
appropriate default backend. For 99% of users, this will be the Agg
647-
backend, which uses the C++
648-
`antigrain <http://antigrain.com>`_
649-
rendering engine to make nice PNGs. The Agg backend is also
650-
configured to recognize requests to generate other output formats
651-
(PDF, PS, EPS, SVG). The easiest way to configure Matplotlib to use
652-
Agg is to call::
653-
654-
# do this before importing pylab or pyplot
655-
import matplotlib
656-
matplotlib.use('Agg')
657-
import matplotlib.pyplot as plt
658-
659-
For more on configuring your backend, see :ref:`what-is-a-backend`.
660-
661-
Alternatively, you can avoid pylab/pyplot altogether, which will give
662-
you a little more control, by calling the API directly as shown in
663-
:doc:`/gallery/user_interfaces/canvasagg`.
664-
665-
You can either generate hardcopy on the filesystem by calling
666-
`.Figure.savefig()`::
667-
668-
# do this before importing pylab or pyplot
669-
import matplotlib
670-
matplotlib.use('Agg')
671-
import matplotlib.pyplot as plt
672-
fig = plt.figure()
673-
ax = fig.add_subplot(111)
674-
ax.plot([1,2,3])
675-
fig.savefig('test.png')
676-
677-
or by saving to a file handle::
678-
679-
import sys
680-
fig.savefig(sys.stdout)
681-
682-
Here is an example using `Pillow <https://pillow.readthedocs.io/en/latest/>`_.
683-
First, the figure is saved to a BytesIO object which is then fed to
684-
Pillow for further processing::
685-
686-
from io import BytesIO
687-
from PIL import Image
688-
imgdata = BytesIO()
689-
fig.savefig(imgdata, format='png')
690-
imgdata.seek(0) # rewind the data
691-
im = Image.open(imgdata)
631+
In general, the simplest solution when using Matplotlib in a web server is
632+
to completely avoid using pyplot (pyplot maintains references to the opened
633+
figures to make `~.matplotlib.pyplot.show` work, but this will cause memory
634+
leaks unless the figures are properly closed). Since Matplotlib 3.1, one
635+
can directly create figures using the `Figure` constructor and save them to
636+
in-memory buffers. The following example uses Flask_, but other frameworks
637+
work similarly::
638+
639+
import base64
640+
from io import BytesIO
641+
642+
from flask import Flask
643+
from matplotlib.figure import Figure
644+
645+
app = Flask(__name__)
646+
647+
@app.route("/")
648+
def hello():
649+
# Generate the figure **without using pyplot**.
650+
fig = Figure()
651+
ax = fig.subplots()
652+
ax.plot([1, 2])
653+
# Save it to a temporary buffer.
654+
buf = BytesIO()
655+
fig.savefig(buf, format="png")
656+
# Embed the result in the html output.
657+
data = base64.b64encode(buf.getbuffer()).decode("ascii")
658+
return f"<img src='data:image/png;base64,{data}'/>"
659+
660+
.. _Flask: http://flask.pocoo.org/
661+
662+
When using Matplotlib versions older than 3.1, it is necessary to explicitly
663+
instantiate an Agg canvas; see e.g. :doc:`/gallery/user_interfaces/canvasagg`.
692664

693665

694666
.. _howto-click-maps:

0 commit comments

Comments
 (0)