##// END OF EJS Templates
enable retina matplotlib figures
MinRK -
Show More
@@ -19,6 +19,7 b' Authors'
19 19 # Imports
20 20 #-----------------------------------------------------------------------------
21 21
22 import struct
22 23 import sys
23 24 from io import BytesIO
24 25
@@ -90,6 +91,7 b' def figsize(sizex, sizey):'
90 91
91 92 def print_figure(fig, fmt='png'):
92 93 """Convert a figure to svg or png for inline display."""
94 from matplotlib import rcParams
93 95 # When there's an empty figure, we shouldn't return anything, otherwise we
94 96 # get big blank areas in the qt console.
95 97 if not fig.axes and not fig.lines:
@@ -98,11 +100,27 b" def print_figure(fig, fmt='png'):"
98 100 fc = fig.get_facecolor()
99 101 ec = fig.get_edgecolor()
100 102 bytes_io = BytesIO()
103 dpi = rcParams['savefig.dpi']
104 if fmt == 'retina':
105 dpi = dpi * 2
101 106 fig.canvas.print_figure(bytes_io, format=fmt, bbox_inches='tight',
102 facecolor=fc, edgecolor=ec)
107 facecolor=fc, edgecolor=ec, dpi=dpi)
103 108 data = bytes_io.getvalue()
104 109 return data
105 110
111 def pngxy(data):
112 """read the width/height from a PNG header"""
113 ihdr = data.index(b'IHDR')
114 # next 8 bytes are width/height
115 w4h4 = data[ihdr+4:ihdr+12]
116 return struct.unpack('>ii', w4h4)
117
118 def retina_figure(fig):
119 """format a figure as a pixel-doubled (retina) PNG"""
120 pngdata = print_figure(fig, fmt='retina')
121 w, h = pngxy(pngdata)
122 metadata = dict(width=w//2, height=h//2)
123 return pngdata, metadata
106 124
107 125 # We need a little factory function here to create the closure where
108 126 # safe_execfile can live.
@@ -147,7 +165,7 b' def mpl_runner(safe_execfile):'
147 165
148 166
149 167 def select_figure_format(shell, fmt):
150 """Select figure format for inline backend, either 'png' or 'svg'.
168 """Select figure format for inline backend, can be 'png', 'retina', or 'svg'.
151 169
152 170 Using this method ensures only one figure format is active at a time.
153 171 """
@@ -160,11 +178,14 b' def select_figure_format(shell, fmt):'
160 178 if fmt=='png':
161 179 svg_formatter.type_printers.pop(Figure, None)
162 180 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png'))
181 elif fmt in ('png2x', 'retina'):
182 svg_formatter.type_printers.pop(Figure, None)
183 png_formatter.for_type(Figure, retina_figure)
163 184 elif fmt=='svg':
164 185 png_formatter.type_printers.pop(Figure, None)
165 186 svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg'))
166 187 else:
167 raise ValueError("supported formats are: 'png', 'svg', not %r"%fmt)
188 raise ValueError("supported formats are: 'png', 'retina', 'svg', not %r" % fmt)
168 189
169 190 # set the format to be used in the backend()
170 191 backend_inline._figure_format = fmt
@@ -18,7 +18,7 b' from IPython.config.configurable import SingletonConfigurable'
18 18 from IPython.core.display import display
19 19 from IPython.core.displaypub import publish_display_data
20 20 from IPython.core.pylabtools import print_figure, select_figure_format
21 from IPython.utils.traitlets import Dict, Instance, CaselessStrEnum, CBool
21 from IPython.utils.traitlets import Dict, Instance, CaselessStrEnum, Bool
22 22 from IPython.utils.warn import warn
23 23
24 24 #-----------------------------------------------------------------------------
@@ -56,7 +56,7 b' class InlineBackend(InlineBackendConfig):'
56 56 inline backend."""
57 57 )
58 58
59 figure_format = CaselessStrEnum(['svg', 'png'], default_value='png', config=True,
59 figure_format = CaselessStrEnum(['svg', 'png', 'retina'], default_value='png', config=True,
60 60 help="The image format for figures with the inline backend.")
61 61
62 62 def _figure_format_changed(self, name, old, new):
@@ -65,7 +65,7 b' class InlineBackend(InlineBackendConfig):'
65 65 else:
66 66 select_figure_format(self.shell, new)
67 67
68 close_figures = CBool(True, config=True,
68 close_figures = Bool(True, config=True,
69 69 help="""Close all figures at the end of each cell.
70 70
71 71 When True, ensures that each cell starts with no active figures, but it
General Comments 0
You need to be logged in to leave comments. Login now