22Define the Figure class that handles all plotting.
33"""
44import os
5+ import sys
56from tempfile import TemporaryDirectory
67import base64
78
8- try :
9- from IPython .display import Image
10- except ImportError :
11- Image = None
129
1310from .clib import Session
1411from .base_plotting import BasePlotting
15- from .exceptions import GMTError , GMTInvalidInput
12+ from .exceptions import GMTInvalidInput
1613from .helpers import (
1714 build_arg_string ,
1815 fmt_docstring ,
2724# This is needed for the sphinx-gallery scraper in pygmt/sphinx_gallery.py
2825SHOWED_FIGURES = []
2926
27+ # Configuration options for Jupyter notebook support
28+ SHOW_CONFIG = {
29+ "external" : True , # Open in an external viewer
30+ "notebook" : True , # Notebook display
31+ "dpi" : 200 , # default DPI
32+ }
33+
34+ # Determine the default display mode
35+ try :
36+ IPython = sys .modules ["IPython" ]
37+ if "IPKernelApp" in IPython .get_ipython ().config : # Jupyter Notebook enabled
38+ SHOW_CONFIG ["notebook" ] = True
39+ SHOW_CONFIG ["external" ] = False
40+ else :
41+ SHOW_CONFIG ["notebook" ] = False
42+ SHOW_CONFIG ["external" ] = True
43+ except KeyError :
44+ SHOW_CONFIG ["notebook" ] = False
45+ SHOW_CONFIG ["external" ] = True
46+
47+ # If the environment variable is set to "true", disable the external viewer.
48+ # Use this for running the tests and building the docs to avoid pop up windows.
49+ if os .environ .get ("PYGMT_DISABLE_EXTERNAL_DISPLAY" , "default" ).lower () == "true" :
50+ SHOW_CONFIG ["external" ] = False
51+
3052
3153class Figure (BasePlotting ):
3254 """
@@ -57,7 +79,7 @@ class Figure(BasePlotting):
5779 >>> fig = Figure()
5880 >>> fig.basemap(region='JP', projection="M3i", frame=True)
5981 >>> # The fig.region attribute shows the WESN bounding box for the figure
60- >>> print(', '.join('{:.2f}'.format(i) for i in fig.region))
82+ >>> print(', '.join('{:.2f}'.format(i) for i in fig.region))
6183 122.94, 145.82, 20.53, 45.52
6284
6385 """
@@ -235,63 +257,38 @@ def savefig(
235257 if show :
236258 launch_external_viewer (fname )
237259
238- def show (self , dpi = 300 , width = 500 , method = "static" ):
260+ def show (self ):
239261 """
240262 Display a preview of the figure.
241263
242- Inserts the preview in the Jupyter notebook output. You will need to
243- have IPython installed for this to work. You should have it if you are
244- using the notebook.
245-
246- If ``method='external'``, makes PDF preview instead and opens it in the
247- default viewer for your operating system (falls back to the default web
248- browser). Note that the external viewer does not block the current
249- process, so this won't work in a script.
264+ Inserts the preview in the Jupyter notebook output, otherwise opens it
265+ in the default viewer for your operating system (falls back to the
266+ default web browser). Note that the external viewer does not block the
267+ current process, so this won't work in a script.
250268
251- Parameters
252- ----------
253- dpi : int
254- The image resolution (dots per inch).
255- width : int
256- Width of the figure shown in the notebook in pixels. Ignored if
257- ``method='external'``.
258- method : str
259- How the figure will be displayed. Options are (1) ``'static'``: PNG
260- preview (default); (2) ``'external'``: PDF preview in an external
261- program.
269+ :func:`pygmt.set_display` can select the default display mode (either
270+ "notebook" or "external").
262271
263- Returns
264- -------
265- img : IPython.display.Image
266- Only if ``method != 'external'`` .
272+ The external viewer can also be disabled by setting the
273+ ``PYGMT_DISABLE_EXTERNAL_DISPLAY`` environment variable to ``true``.
274+ This is mainly used for running our tests and building the
275+ documentation .
267276
268277 """
269278 # Module level variable to know which figures had their show method
270279 # called. Needed for the sphinx-gallery scraper.
271280 SHOWED_FIGURES .append (self )
272281
273- if method not in ["static" , "external" ]:
274- raise GMTInvalidInput ("Invalid show method '{}'." .format (method ))
275- if method == "external" :
276- pdf = self ._preview (fmt = "pdf" , dpi = dpi , anti_alias = False , as_bytes = False )
277- launch_external_viewer (pdf )
278- img = None
279- elif method == "static" :
280- png = self ._preview (
281- fmt = "png" , dpi = dpi , anti_alias = True , as_bytes = True , transparent = True
282+ if SHOW_CONFIG ["notebook" ]:
283+ png = self ._repr_png_ ()
284+ if IPython is not None :
285+ IPython .display .display (IPython .display .Image (data = png ))
286+
287+ if SHOW_CONFIG ["external" ]:
288+ pdf = self ._preview (
289+ fmt = "pdf" , dpi = SHOW_CONFIG ["dpi" ], anti_alias = False , as_bytes = False
282290 )
283- if Image is None :
284- raise GMTError (
285- " " .join (
286- [
287- "Cannot find IPython." ,
288- "Make sure you have it installed" ,
289- "or use 'external=True' to open in an external viewer." ,
290- ]
291- )
292- )
293- img = Image (data = png , width = width )
294- return img
291+ launch_external_viewer (pdf )
295292
296293 def shift_origin (self , xshift = None , yshift = None ):
297294 """
@@ -362,7 +359,9 @@ def _repr_png_(self):
362359 Show a PNG preview if the object is returned in an interactive shell.
363360 For the Jupyter notebook or IPython Qt console.
364361 """
365- png = self ._preview (fmt = "png" , dpi = 70 , anti_alias = True , as_bytes = True )
362+ png = self ._preview (
363+ fmt = "png" , dpi = SHOW_CONFIG ["dpi" ], anti_alias = True , as_bytes = True
364+ )
366365 return png
367366
368367 def _repr_html_ (self ):
@@ -374,3 +373,29 @@ def _repr_html_(self):
374373 base64_png = base64 .encodebytes (raw_png )
375374 html = '<img src="data:image/png;base64,{image}" width="{width}px">'
376375 return html .format (image = base64_png .decode ("utf-8" ), width = 500 )
376+
377+
378+ def set_display (mode , dpi = 200 ):
379+ """Set the display mode.
380+
381+ Parameters
382+ ----------
383+ mode : str
384+ Choose from "notebook" (for inline display in Jupyter notebook)
385+ or "external" (for displaying preview using the external viewer).
386+
387+ dpi : int
388+ Set the default DPI (dots-per-inch) used for PNG image previews that
389+ are inserted into the notebook.
390+ """
391+ if mode == "notebook" :
392+ SHOW_CONFIG ["notebook" ] = True
393+ SHOW_CONFIG ["external" ] = False
394+ elif mode == "external" :
395+ SHOW_CONFIG ["notebook" ] = False
396+ SHOW_CONFIG ["external" ] = True
397+ else :
398+ raise GMTInvalidInput (
399+ f'Invalid display mode { mode } , should be either "notebook" or "external".'
400+ )
401+ SHOW_CONFIG ["dpi" ] = dpi
0 commit comments