Show More
@@ -95,7 +95,7 b' def figsize(sizex, sizey):' | |||||
95 |
|
95 | |||
96 |
|
96 | |||
97 | def print_figure(fig, fmt='png', quality=90): |
|
97 | def print_figure(fig, fmt='png', quality=90): | |
98 |
"""Convert a figure to svg, |
|
98 | """Convert a figure to svg, png or jpg for inline display.""" | |
99 | from matplotlib import rcParams |
|
99 | from matplotlib import rcParams | |
100 | # When there's an empty figure, we shouldn't return anything, otherwise we |
|
100 | # When there's an empty figure, we shouldn't return anything, otherwise we | |
101 | # get big blank areas in the qt console. |
|
101 | # get big blank areas in the qt console. | |
@@ -164,7 +164,7 b' def mpl_runner(safe_execfile):' | |||||
164 |
|
164 | |||
165 |
|
165 | |||
166 | def select_figure_format(shell, fmt, quality): |
|
166 | def select_figure_format(shell, fmt, quality): | |
167 | """Select figure format for inline backend, can be 'png', 'retina', or 'svg'. |
|
167 | """Select figure format for inline backend, can be 'png', 'retina', 'jpg', or 'svg'. | |
168 |
|
168 | |||
169 | Using this method ensures only one figure format is active at a time. |
|
169 | Using this method ensures only one figure format is active at a time. | |
170 | """ |
|
170 | """ | |
@@ -175,20 +175,18 b' def select_figure_format(shell, fmt, quality):' | |||||
175 | png_formatter = shell.display_formatter.formatters['image/png'] |
|
175 | png_formatter = shell.display_formatter.formatters['image/png'] | |
176 | jpg_formatter = shell.display_formatter.formatters['image/jpeg'] |
|
176 | jpg_formatter = shell.display_formatter.formatters['image/jpeg'] | |
177 |
|
177 | |||
|
178 | [ f.type_printers.pop(Figure, None) for f in {svg_formatter, png_formatter, jpg_formatter} ] | |||
|
179 | ||||
178 | if fmt == 'png': |
|
180 | if fmt == 'png': | |
179 | svg_formatter.pop(Figure, None) |
|
|||
180 | png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png')) |
|
181 | png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png')) | |
181 | elif fmt in ('jpg', 'jpeg'): |
|
|||
182 | svg_formatter.type_printers.pop(Figure, None) |
|
|||
183 | jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', quality)) |
|
|||
184 | elif fmt in ('png2x', 'retina'): |
|
182 | elif fmt in ('png2x', 'retina'): | |
185 | svg_formatter.pop(Figure, None) |
|
|||
186 | png_formatter.for_type(Figure, retina_figure) |
|
183 | png_formatter.for_type(Figure, retina_figure) | |
|
184 | elif fmt in ('jpg', 'jpeg'): | |||
|
185 | jpg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'jpg', quality)) | |||
187 | elif fmt == 'svg': |
|
186 | elif fmt == 'svg': | |
188 | png_formatter.pop(Figure, None) |
|
|||
189 | svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg')) |
|
187 | svg_formatter.for_type(Figure, lambda fig: print_figure(fig, 'svg')) | |
190 | else: |
|
188 | else: | |
191 | raise ValueError("supported formats are: 'png', 'retina', 'svg', not %r" % fmt) |
|
189 | raise ValueError("supported formats are: 'png', 'retina', 'svg', 'jpg', not %r" % fmt) | |
192 |
|
190 | |||
193 | # set the format to be used in the backend() |
|
191 | # set the format to be used in the backend() | |
194 | backend_inline._figure_format = fmt |
|
192 | backend_inline._figure_format = fmt |
@@ -21,11 +21,15 b' from IPython.utils.warn import warn' | |||||
21 | # Configurable for inline backend options |
|
21 | # Configurable for inline backend options | |
22 | #----------------------------------------------------------------------------- |
|
22 | #----------------------------------------------------------------------------- | |
23 |
|
23 | |||
24 | try: |
|
24 | def pil_available(): | |
25 | from PIL import Image |
|
25 | """Test if PIL/Pillow is available""" | |
26 | has_pil = True |
|
26 | out = False | |
27 | except: |
|
27 | try: | |
28 | has_pil = False |
|
28 | from PIL import Image | |
|
29 | out = True | |||
|
30 | except: | |||
|
31 | pass | |||
|
32 | return out | |||
29 |
|
33 | |||
30 | # inherit from InlineBackendConfig for deprecation purposes |
|
34 | # inherit from InlineBackendConfig for deprecation purposes | |
31 | class InlineBackendConfig(SingletonConfigurable): |
|
35 | class InlineBackendConfig(SingletonConfigurable): | |
@@ -59,28 +63,28 b' class InlineBackend(InlineBackendConfig):' | |||||
59 | inline backend.""" |
|
63 | inline backend.""" | |
60 | ) |
|
64 | ) | |
61 |
|
65 | |||
62 | fmts = ['svg', 'png', 'retina'] |
|
|||
63 |
|
66 | |||
64 | if has_pil: |
|
67 | figure_format = CaselessStrEnum(['svg', 'png', 'retina', 'jpg'], | |
65 | # If we have PIL using jpeg as inline image format can save some bytes. |
|
68 | default_value='png', config=True, | |
66 | fmts.append('jpg') |
|
69 | help="""The image format for figures with the inline backend. | |
67 |
|
70 | JPEG requires the PIL/Pillow library.""") | ||
68 | # Matplotlib's JPEG printer supports a quality option that can be tweaked. |
|
|||
69 | # We expose it only if PIL is available so the user isn't confused. But it |
|
|||
70 | # isn't guarded by "has_pil" test because core/pylabtools.py expects this |
|
|||
71 | # field OR we need to propagate the has_pil test to that module too. |
|
|||
72 | quality = Int(default_value=90, config=has_pil, |
|
|||
73 | help="Quality of compression [0-100], currently for lossy JPEG only.") |
|
|||
74 |
|
||||
75 | figure_format = CaselessStrEnum(fmts, default_value='png', config=True, |
|
|||
76 | help="The image format for figures with the inline backend.") |
|
|||
77 |
|
71 | |||
78 | def _figure_format_changed(self, name, old, new): |
|
72 | def _figure_format_changed(self, name, old, new): | |
79 | from IPython.core.pylabtools import select_figure_format |
|
73 | from IPython.core.pylabtools import select_figure_format | |
|
74 | if new in {"jpg", "jpeg"}: | |||
|
75 | if not pil_available(): | |||
|
76 | raise TraitError("Requires PIL/Pillow for JPG figures") | |||
80 | if self.shell is None: |
|
77 | if self.shell is None: | |
81 | return |
|
78 | return | |
82 | else: |
|
79 | else: | |
83 | select_figure_format(self.shell, new) |
|
80 | select_figure_format(self.shell, new) | |
|
81 | ||||
|
82 | quality = Int(default_value=90, config=True, | |||
|
83 | help="Quality of compression [0-100], currently for lossy JPEG only.") | |||
|
84 | ||||
|
85 | def _quality_changed(self, name, old, new): | |||
|
86 | if new < 0 or new > 100: | |||
|
87 | raise TraitError("figure quality must be in [0-100] range.") | |||
84 |
|
88 | |||
85 | close_figures = Bool(True, config=True, |
|
89 | close_figures = Bool(True, config=True, | |
86 | help="""Close all figures at the end of each cell. |
|
90 | help="""Close all figures at the end of each cell. |
General Comments 0
You need to be logged in to leave comments.
Login now