From b92ba6bc0899e9a731ea847eb415c3d4139440fc Mon Sep 17 00:00:00 2001 From: Benjamin Reedlunn Date: Sun, 1 Feb 2015 20:22:29 -0700 Subject: [PATCH 1/8] Added the rcParams 'pdf.combine_images', 'svg.combine_images', and 'ps.combine_images' to permit users to decide whether they want the vector graphics backend to combine all images within a set of axes into a single image. (If images do not get combined, users can open vector graphics files in Adobe Illustrator or Inkscape and edit each image individually.) Also changed 'renderer.option_nocomposite' to the clearer name 'renderer.option_combine_images'. Improved combine image tests to actually count the number of images in the vector graphics files. Also replaced the rcParams 'pdf.combine_images', 'svg.combine_images', and 'ps.combine_images' with 'vector_backends.combine_images' Corrected PEP8 coding standard violations Updated 'combine_images' tests for PS and SVG backends to hopefully make them Python 3 compatible. Fixed some PEP8 violations to leave the code cleaner than I found it. Fixed PEP8 violations introduced in my effort to fix PEP8 violations in my last commit. Changed the rcParam option name from 'vector_graphics.combine_images' to 'image.combine_images', and updated the matplotlibrc.template. Update the backend tests with the new rcParam name 'image.combine_images' Added the rcParams 'pdf.combine_images', 'svg.combine_images', and 'ps.combine_images' to permit users to decide whether they want the vector graphics backend to combine all images within a set of axes into a single image. (If images do not get combined, users can open vector graphics files in Adobe Illustrator or Inkscape and edit each image individually.) Also changed 'renderer.option_nocomposite' to the clearer name 'renderer.option_combine_images'. Improved combine image tests to actually count the number of images in the vector graphics files. Also replaced the rcParams 'pdf.combine_images', 'svg.combine_images', and 'ps.combine_images' with 'vector_backends.combine_images' Corrected PEP8 coding standard violations Updated 'combine_images' tests for PS and SVG backends to hopefully make them Python 3 compatible. Fixed some PEP8 violations to leave the code cleaner than I found it. Fixed PEP8 violations introduced in my effort to fix PEP8 violations in my last commit. Changed the rcParam option name from 'vector_graphics.combine_images' to 'image.combine_images', and updated the matplotlibrc.template. Update the backend tests with the new rcParam name 'image.combine_images' --- CHANGELOG | 8 +++++ lib/matplotlib/axes/_base.py | 20 ++++++------- lib/matplotlib/backend_bases.py | 6 ++-- lib/matplotlib/backends/backend_agg.py | 8 ++--- lib/matplotlib/backends/backend_macosx.py | 4 +-- lib/matplotlib/backends/backend_mixed.py | 3 +- lib/matplotlib/backends/backend_pdf.py | 12 ++++++-- lib/matplotlib/backends/backend_ps.py | 7 +++++ lib/matplotlib/backends/backend_svg.py | 10 +++++-- lib/matplotlib/figure.py | 14 ++++----- lib/matplotlib/rcsetup.py | 4 +++ ...site_alpha.pdf => image_combine_alpha.pdf} | Bin ...site_alpha.png => image_combine_alpha.png} | Bin ...site_alpha.svg => image_combine_alpha.svg} | 0 ...round.pdf => image_combine_background.pdf} | Bin ...round.png => image_combine_background.png} | Bin ...round.svg => image_combine_background.svg} | 0 lib/matplotlib/tests/test_backend_pdf.py | 28 +++++++++++++++--- lib/matplotlib/tests/test_backend_ps.py | 26 +++++++++++++++- lib/matplotlib/tests/test_backend_svg.py | 25 ++++++++++++++++ lib/matplotlib/tests/test_image.py | 10 +++---- matplotlibrc.template | 4 +++ 22 files changed, 146 insertions(+), 43 deletions(-) rename lib/matplotlib/tests/baseline_images/test_image/{image_composite_alpha.pdf => image_combine_alpha.pdf} (100%) rename lib/matplotlib/tests/baseline_images/test_image/{image_composite_alpha.png => image_combine_alpha.png} (100%) rename lib/matplotlib/tests/baseline_images/test_image/{image_composite_alpha.svg => image_combine_alpha.svg} (100%) rename lib/matplotlib/tests/baseline_images/test_image/{image_composite_background.pdf => image_combine_background.pdf} (100%) rename lib/matplotlib/tests/baseline_images/test_image/{image_composite_background.png => image_combine_background.png} (100%) rename lib/matplotlib/tests/baseline_images/test_image/{image_composite_background.svg => image_combine_background.svg} (100%) diff --git a/CHANGELOG b/CHANGELOG index 38b1fe4e97aa..a1496e3da262 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,14 @@ corner masking. This is controlled by the 'corner_mask' keyword in plotting commands 'contour' and 'contourf'. - IMT +2015-01-31 Added the rcParam 'image.combine_images' to permit users + to decide whether they want the vector graphics backends to combine + all images within a set of axes into a single image. (If images do + not get combined, users can open vector graphics files in Adobe + Illustrator or Inkscape and edit each image individually.) Also + changed 'renderer.option_nocomposite' to the clearer name + 'renderer.option_combine_images'. + 2015-01-23 Text bounding boxes are now computed with advance width rather than ink area. This may result in slightly different placement of text. diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index c8e5b3cbb955..a82e0cff75bc 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -30,8 +30,6 @@ import matplotlib.text as mtext import matplotlib.image as mimage from matplotlib.artist import allow_rasterization - - from matplotlib.cbook import iterable rcParams = matplotlib.rcParams @@ -1241,7 +1239,9 @@ def apply_aspect(self, position=None): Xsize = ysize / data_ratio Xmarg = Xsize - xr Ymarg = Ysize - yr - xm = 0 # Setting these targets to, e.g., 0.05*xr does not seem to help + # Setting these targets to, e.g., 0.05*xr does not seem to + # help. + xm = 0 ym = 0 changex = (self in self._shared_y_axes and @@ -2028,13 +2028,13 @@ def draw(self, renderer=None, inframe=False): dsu = [(a.zorder, a) for a in artists if not a.get_animated()] - # add images to dsu if the backend support compositing. - # otherwise, does the manaul compositing without adding images to dsu. - if len(self.images) <= 1 or renderer.option_image_nocomposite(): + # add images to dsu if the backend supports combining images. + # otherwise, perform manual combining, without adding images to dsu. + if len(self.images) <= 1 or not renderer.option_combine_images(): dsu.extend([(im.zorder, im) for im in self.images]) - _do_composite = False + _combine_images = False else: - _do_composite = True + _combine_images = True dsu.sort(key=itemgetter(0)) @@ -2054,8 +2054,8 @@ def draw(self, renderer=None, inframe=False): if self.axison and self._frameon: self.patch.draw(renderer) - if _do_composite: - # make a composite image blending alpha + if _combine_images: + # combine images, blending alpha # list of (mimage.Image, ox, oy) zorder_images = [(im.zorder, im) for im in self.images diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index edcc81f95f89..d191dcb90d8a 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -527,12 +527,12 @@ def draw_image(self, gc, x, y, im): """ raise NotImplementedError - def option_image_nocomposite(self): + def option_combine_images(self): """ override this method for renderers that do not necessarily - want to rescale and composite raster images. (like SVG) + want to rescale and composite raster images. (like SVG, PDF, or PS) """ - return False + return True def option_scale_image(self): """ diff --git a/lib/matplotlib/backends/backend_agg.py b/lib/matplotlib/backends/backend_agg.py index 687e52bcfc78..1c77d81bb746 100644 --- a/lib/matplotlib/backends/backend_agg.py +++ b/lib/matplotlib/backends/backend_agg.py @@ -322,11 +322,11 @@ def buffer_rgba(self): def clear(self): self._renderer.clear() - def option_image_nocomposite(self): - # It is generally faster to composite each image directly to - # the Figure, and there's no file size benefit to compositing + def option_combine_images(self): + # It is generally faster to write each image directly to + # the Figure, and there's no file size benefit to combining images # with the Agg backend - return True + return False def option_scale_image(self): """ diff --git a/lib/matplotlib/backends/backend_macosx.py b/lib/matplotlib/backends/backend_macosx.py index 43434e374e1d..44d1a8509f89 100755 --- a/lib/matplotlib/backends/backend_macosx.py +++ b/lib/matplotlib/backends/backend_macosx.py @@ -170,8 +170,8 @@ def flipy(self): def points_to_pixels(self, points): return points/72.0 * self.dpi - def option_image_nocomposite(self): - return True + def option_combine_images(self): + return False class GraphicsContextMac(_macosx.GraphicsContext, GraphicsContextBase): diff --git a/lib/matplotlib/backends/backend_mixed.py b/lib/matplotlib/backends/backend_mixed.py index ee48f9274bbe..4845e63b6e99 100644 --- a/lib/matplotlib/backends/backend_mixed.py +++ b/lib/matplotlib/backends/backend_mixed.py @@ -43,7 +43,6 @@ def __init__(self, figure, width, height, dpi, vector_renderer, self._height = height self.dpi = dpi - assert not vector_renderer.option_image_nocomposite() self._vector_renderer = vector_renderer self._raster_renderer = None @@ -64,7 +63,7 @@ def __init__(self, figure, width, height, dpi, vector_renderer, draw_path_collection draw_quad_mesh draw_tex draw_text finalize flipy get_canvas_width_height get_image_magnification get_texmanager get_text_width_height_descent new_gc open_group - option_image_nocomposite points_to_pixels strip_math + option_combine_images points_to_pixels strip_math start_filter stop_filter draw_gouraud_triangle draw_gouraud_triangles option_scale_image _text2path _get_text_path_transform height width diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index e03ab01ade93..1a2d7240e288 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -462,8 +462,8 @@ def __init__(self, filename): self.fontNames = {} # maps filenames to internal font names self.nextFont = 1 # next free internal font name self.dviFontInfo = {} # information on dvi fonts - self.type1Descriptors = {} # differently encoded Type-1 fonts may - # share the same descriptor + # differently encoded Type-1 fonts may share the same descriptor + self.type1Descriptors = {} self.used_characters = {} self.alphaStates = {} # maps alpha values to graphics state objects @@ -1475,6 +1475,7 @@ def is_date(x): check_trapped = (lambda x: isinstance(x, Name) and x.name in ('True', 'False', 'Unknown')) + keywords = {'Title': is_string_like, 'Author': is_string_like, 'Subject': is_string_like, @@ -1576,6 +1577,13 @@ def option_scale_image(self): """ return True + def option_combine_images(self): + """ + return whether to combine multiple images on a set of axes into one + image + """ + return rcParams['image.combine_images'] + def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None): self.check_gc(gc) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index 1474d95d9c26..ffac6229914d 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -451,6 +451,13 @@ def option_scale_image(self): ps backend support arbitrary scaling of image. """ return True + + def option_combine_images(self): + """ + return whether to combine multiple images on a set of axes into one + image + """ + return rcParams['image.combine_images'] def _get_image_h_w_bits_command(self, im): if im.is_grayscale: diff --git a/lib/matplotlib/backends/backend_svg.py b/lib/matplotlib/backends/backend_svg.py index 865acf66620e..f1ea9a52ef9d 100644 --- a/lib/matplotlib/backends/backend_svg.py +++ b/lib/matplotlib/backends/backend_svg.py @@ -527,11 +527,15 @@ def open_group(self, s, gid=None): def close_group(self, s): self.writer.end('g') - def option_image_nocomposite(self): + def option_combine_images(self): """ - if svg.image_noscale is True, compositing multiple images into one is prohibited + if svg.image_noscale is True, combining multiple images into one is + prohibited """ - return rcParams['svg.image_noscale'] + if rcParams['svg.image_noscale']: + return False + else: + return rcParams['image.combine_images'] def _convert_path(self, path, transform=None, clip=None, simplify=None): if clip: diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index 986870c78140..8d99f9a69de3 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -249,7 +249,7 @@ class Figure(Artist): *suppressComposite* For multiple figure images, the figure will make composite - images depending on the renderer option_image_nocomposite + images depending on the renderer option_combine_images function. If suppressComposite is True|False, this will override the renderer. """ @@ -1045,16 +1045,16 @@ def draw(self, renderer): # override the renderer default if self.suppressComposite # is not None - not_composite = renderer.option_image_nocomposite() + combine_images = renderer.option_combine_images() if self.suppressComposite is not None: - not_composite = self.suppressComposite + combine_images = not self.suppressComposite - if (len(self.images) <= 1 or not_composite or + if (len(self.images) <= 1 or not combine_images or not cbook.allequal([im.origin for im in self.images])): for a in self.images: dsu.append((a.get_zorder(), a, a.draw, [renderer])) else: - # make a composite image blending alpha + # make a combined image, blending alpha # list of (_image.Image, ox, oy) mag = renderer.get_image_magnification() ims = [(im.make_image(mag), im.ox, im.oy, im.get_alpha()) @@ -1067,7 +1067,7 @@ def draw(self, renderer): im.is_grayscale = False l, b, w, h = self.bbox.bounds - def draw_composite(): + def draw_combined_image(): gc = renderer.new_gc() gc.set_clip_rectangle(self.bbox) gc.set_clip_path(self.get_clip_path()) @@ -1075,7 +1075,7 @@ def draw_composite(): gc.restore() dsu.append((self.images[0].get_zorder(), self.images[0], - draw_composite, [])) + draw_combined_image, [])) # render the axes for a in self.axes: diff --git a/lib/matplotlib/rcsetup.py b/lib/matplotlib/rcsetup.py index 51289832c6b1..4c1e40bc2f98 100644 --- a/lib/matplotlib/rcsetup.py +++ b/lib/matplotlib/rcsetup.py @@ -595,6 +595,9 @@ def __call__(self, s): 'image.lut': [256, validate_int], # lookup table 'image.origin': ['upper', six.text_type], # lookup table 'image.resample': [False, validate_bool], + # Force vector graphics backends to combine all images on a set of axes + # into a single image + 'image.combine_images': [True, validate_bool], # contour props 'contour.negative_linestyle': ['dashed', @@ -764,6 +767,7 @@ def __call__(self, s): # Maintain shell focus for TkAgg 'tk.window_focus': [False, validate_bool], 'tk.pythoninspect': [False, validate_tkpythoninspect], # obsolete + # Set the papersize/type 'ps.papersize': ['letter', validate_ps_papersize], 'ps.useafm': [False, validate_bool], # Set PYTHONINSPECT diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.pdf b/lib/matplotlib/tests/baseline_images/test_image/image_combine_alpha.pdf similarity index 100% rename from lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.pdf rename to lib/matplotlib/tests/baseline_images/test_image/image_combine_alpha.pdf diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.png b/lib/matplotlib/tests/baseline_images/test_image/image_combine_alpha.png similarity index 100% rename from lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.png rename to lib/matplotlib/tests/baseline_images/test_image/image_combine_alpha.png diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.svg b/lib/matplotlib/tests/baseline_images/test_image/image_combine_alpha.svg similarity index 100% rename from lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.svg rename to lib/matplotlib/tests/baseline_images/test_image/image_combine_alpha.svg diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_composite_background.pdf b/lib/matplotlib/tests/baseline_images/test_image/image_combine_background.pdf similarity index 100% rename from lib/matplotlib/tests/baseline_images/test_image/image_composite_background.pdf rename to lib/matplotlib/tests/baseline_images/test_image/image_combine_background.pdf diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_composite_background.png b/lib/matplotlib/tests/baseline_images/test_image/image_combine_background.png similarity index 100% rename from lib/matplotlib/tests/baseline_images/test_image/image_composite_background.png rename to lib/matplotlib/tests/baseline_images/test_image/image_combine_background.png diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_composite_background.svg b/lib/matplotlib/tests/baseline_images/test_image/image_combine_background.svg similarity index 100% rename from lib/matplotlib/tests/baseline_images/test_image/image_composite_background.svg rename to lib/matplotlib/tests/baseline_images/test_image/image_combine_background.svg diff --git a/lib/matplotlib/tests/test_backend_pdf.py b/lib/matplotlib/tests/test_backend_pdf.py index 0e693402ca16..8311be430cf9 100644 --- a/lib/matplotlib/tests/test_backend_pdf.py +++ b/lib/matplotlib/tests/test_backend_pdf.py @@ -9,8 +9,8 @@ import os import numpy as np - from matplotlib import cm, rcParams +from matplotlib.backends.backend_pdf import PdfPages from matplotlib import pyplot as plt from matplotlib.testing.decorators import (image_comparison, knownfailureif, cleanup) @@ -42,7 +42,6 @@ def test_type42(): @cleanup def test_multipage_pagecount(): - from matplotlib.backends.backend_pdf import PdfPages with PdfPages(io.BytesIO()) as pdf: assert pdf.get_pagecount() == 0 fig = plt.figure() @@ -58,7 +57,7 @@ def test_multipage_pagecount(): def test_multipage_keep_empty(): from matplotlib.backends.backend_pdf import PdfPages from tempfile import NamedTemporaryFile - ### test empty pdf files + # test empty pdf files # test that an empty pdf is left behind with keep_empty=True (default) with NamedTemporaryFile(delete=False) as tmp: with PdfPages(tmp) as pdf: @@ -69,7 +68,7 @@ def test_multipage_keep_empty(): with PdfPages(filename, keep_empty=False) as pdf: pass assert not os.path.exists(filename) - ### test pdf files with content, they should never be deleted + # test pdf files with content, they should never be deleted fig = plt.figure() ax = fig.add_subplot(111) ax.plot([1, 2, 3]) @@ -87,3 +86,24 @@ def test_multipage_keep_empty(): pdf.savefig() assert os.path.exists(filename) os.remove(filename) + + +@cleanup +def test_combine_images(): + #Test that figures can be saved with and without combining multiple images + #(on a single set of axes) into a single image. + X, Y = np.meshgrid(np.arange(-5, 5, 1), np.arange(-5, 5, 1)) + Z = np.sin(Y ** 2) + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1) + ax.set_xlim(0, 3) + ax.imshow(Z, extent=[0, 1, 0, 1]) + ax.imshow(Z[::-1], extent=[2, 3, 0, 1]) + plt.rcParams['image.combine_images'] = True + with PdfPages(io.BytesIO()) as pdf: + fig.savefig(pdf, format="pdf") + assert len(pdf._file.images.keys()) == 1 + plt.rcParams['image.combine_images'] = False + with PdfPages(io.BytesIO()) as pdf: + fig.savefig(pdf, format="pdf") + assert len(pdf._file.images.keys()) == 2 diff --git a/lib/matplotlib/tests/test_backend_ps.py b/lib/matplotlib/tests/test_backend_ps.py index 4b92678d09e5..09e73db939ff 100644 --- a/lib/matplotlib/tests/test_backend_ps.py +++ b/lib/matplotlib/tests/test_backend_ps.py @@ -5,7 +5,7 @@ import io import re - +import numpy as np import six import matplotlib @@ -86,6 +86,30 @@ def test_savefig_to_stringio_with_usetex_eps(): _test_savefig_to_stringio(format='eps') +@cleanup +def test_combine_images(): + #Test that figures can be saved with and without combining multiple images + #(on a single set of axes) into a single image. + X, Y = np.meshgrid(np.arange(-5, 5, 1), np.arange(-5, 5, 1)) + Z = np.sin(Y ** 2) + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1) + ax.set_xlim(0, 3) + ax.imshow(Z, extent=[0, 1, 0, 1]) + ax.imshow(Z[::-1], extent=[2, 3, 0, 1]) + plt.rcParams['image.combine_images'] = True + with io.BytesIO() as ps: + fig.savefig(ps, format="ps") + ps.seek(0) + buff = ps.read() + assert buff.count(six.b(' colorimage')) == 1 + plt.rcParams['image.combine_images'] = False + with io.BytesIO() as ps: + fig.savefig(ps, format="ps") + ps.seek(0) + buff = ps.read() + assert buff.count(six.b(' colorimage')) == 2 + if __name__ == '__main__': import nose nose.runmodule(argv=['-s', '--with-doctest'], exit=False) diff --git a/lib/matplotlib/tests/test_backend_svg.py b/lib/matplotlib/tests/test_backend_svg.py index 4d2632bc3afa..5de764d395f4 100644 --- a/lib/matplotlib/tests/test_backend_svg.py +++ b/lib/matplotlib/tests/test_backend_svg.py @@ -55,6 +55,31 @@ def test_noscale(): plt.rcParams['svg.image_noscale'] = True +@cleanup +def test_combine_images(): + #Test that figures can be saved with and without combining multiple images + #(on a single set of axes) into a single image. + X, Y = np.meshgrid(np.arange(-5, 5, 1), np.arange(-5, 5, 1)) + Z = np.sin(Y ** 2) + fig = plt.figure() + ax = fig.add_subplot(1, 1, 1) + ax.set_xlim(0, 3) + ax.imshow(Z, extent=[0, 1, 0, 1]) + ax.imshow(Z[::-1], extent=[2, 3, 0, 1]) + plt.rcParams['image.combine_images'] = True + with BytesIO() as svg: + fig.savefig(svg, format="svg") + svg.seek(0) + buff = svg.read() + assert buff.count(six.b(' Date: Fri, 27 Feb 2015 10:21:13 -0700 Subject: [PATCH 2/8] Updated CHANGELOG to put proposed change at the top of the list Reverted from the 'combine_images' terminology back to the 'composite_image' terminology. With this terminology, we can keep the method name 'renderer.option_image_nocomposite()', and maintain backwards compatibility. --- CHANGELOG | 14 ++++++-------- lib/matplotlib/axes/_base.py | 14 +++++++------- lib/matplotlib/backend_bases.py | 6 +++--- lib/matplotlib/backends/backend_agg.py | 8 ++++---- lib/matplotlib/backends/backend_macosx.py | 4 ++-- lib/matplotlib/backends/backend_mixed.py | 2 +- lib/matplotlib/backends/backend_pdf.py | 8 ++++---- lib/matplotlib/backends/backend_ps.py | 8 ++++---- lib/matplotlib/backends/backend_svg.py | 10 +++++----- lib/matplotlib/figure.py | 12 ++++++------ lib/matplotlib/rcsetup.py | 6 +++--- ...ombine_alpha.pdf => image_composite_alpha.pdf} | Bin ...ombine_alpha.png => image_composite_alpha.png} | Bin ...ombine_alpha.svg => image_composite_alpha.svg} | 0 ...kground.pdf => image_composite_background.pdf} | Bin ...kground.png => image_composite_background.png} | Bin ...kground.svg => image_composite_background.svg} | 0 lib/matplotlib/tests/test_backend_pdf.py | 8 ++++---- lib/matplotlib/tests/test_backend_ps.py | 8 ++++---- lib/matplotlib/tests/test_backend_svg.py | 8 ++++---- lib/matplotlib/tests/test_image.py | 8 ++++---- matplotlibrc.template | 4 ++-- 22 files changed, 63 insertions(+), 65 deletions(-) rename lib/matplotlib/tests/baseline_images/test_image/{image_combine_alpha.pdf => image_composite_alpha.pdf} (100%) rename lib/matplotlib/tests/baseline_images/test_image/{image_combine_alpha.png => image_composite_alpha.png} (100%) rename lib/matplotlib/tests/baseline_images/test_image/{image_combine_alpha.svg => image_composite_alpha.svg} (100%) rename lib/matplotlib/tests/baseline_images/test_image/{image_combine_background.pdf => image_composite_background.pdf} (100%) rename lib/matplotlib/tests/baseline_images/test_image/{image_combine_background.png => image_composite_background.png} (100%) rename lib/matplotlib/tests/baseline_images/test_image/{image_combine_background.svg => image_composite_background.svg} (100%) diff --git a/CHANGELOG b/CHANGELOG index a1496e3da262..506d5ed307a7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,15 +1,13 @@ +2015-02-27 Added the rcParam 'image.composite_image' to permit users + to decide whether they want the vector graphics backends to combine + all images within a set of axes into a single composite image. + (If images do not get combined, users can open vector graphics files + in Adobe Illustrator or Inkscape and edit each image individually.) + 2015-02-19 Rewrite of C++ code that calculates contours to add support for corner masking. This is controlled by the 'corner_mask' keyword in plotting commands 'contour' and 'contourf'. - IMT -2015-01-31 Added the rcParam 'image.combine_images' to permit users - to decide whether they want the vector graphics backends to combine - all images within a set of axes into a single image. (If images do - not get combined, users can open vector graphics files in Adobe - Illustrator or Inkscape and edit each image individually.) Also - changed 'renderer.option_nocomposite' to the clearer name - 'renderer.option_combine_images'. - 2015-01-23 Text bounding boxes are now computed with advance width rather than ink area. This may result in slightly different placement of text. diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index a82e0cff75bc..e7b9696947c9 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -2028,13 +2028,13 @@ def draw(self, renderer=None, inframe=False): dsu = [(a.zorder, a) for a in artists if not a.get_animated()] - # add images to dsu if the backend supports combining images. - # otherwise, perform manual combining, without adding images to dsu. - if len(self.images) <= 1 or not renderer.option_combine_images(): + # add images to dsu if the backend supports compositing. + # otherwise, does the manual compositing without adding images to dsu. + if len(self.images) <= 1 or renderer.option_image_nocomposite(): dsu.extend([(im.zorder, im) for im in self.images]) - _combine_images = False + _do_composite = False else: - _combine_images = True + _do_composite = True dsu.sort(key=itemgetter(0)) @@ -2054,8 +2054,8 @@ def draw(self, renderer=None, inframe=False): if self.axison and self._frameon: self.patch.draw(renderer) - if _combine_images: - # combine images, blending alpha + if _do_composite: + # make a composite image, blending alpha # list of (mimage.Image, ox, oy) zorder_images = [(im.zorder, im) for im in self.images diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index d191dcb90d8a..8ef174652621 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -527,12 +527,12 @@ def draw_image(self, gc, x, y, im): """ raise NotImplementedError - def option_combine_images(self): + def option_image_nocomposite(self): """ - override this method for renderers that do not necessarily + override this method for renderers that do not necessarily always want to rescale and composite raster images. (like SVG, PDF, or PS) """ - return True + return False def option_scale_image(self): """ diff --git a/lib/matplotlib/backends/backend_agg.py b/lib/matplotlib/backends/backend_agg.py index 1c77d81bb746..687e52bcfc78 100644 --- a/lib/matplotlib/backends/backend_agg.py +++ b/lib/matplotlib/backends/backend_agg.py @@ -322,11 +322,11 @@ def buffer_rgba(self): def clear(self): self._renderer.clear() - def option_combine_images(self): - # It is generally faster to write each image directly to - # the Figure, and there's no file size benefit to combining images + def option_image_nocomposite(self): + # It is generally faster to composite each image directly to + # the Figure, and there's no file size benefit to compositing # with the Agg backend - return False + return True def option_scale_image(self): """ diff --git a/lib/matplotlib/backends/backend_macosx.py b/lib/matplotlib/backends/backend_macosx.py index 44d1a8509f89..43434e374e1d 100755 --- a/lib/matplotlib/backends/backend_macosx.py +++ b/lib/matplotlib/backends/backend_macosx.py @@ -170,8 +170,8 @@ def flipy(self): def points_to_pixels(self, points): return points/72.0 * self.dpi - def option_combine_images(self): - return False + def option_image_nocomposite(self): + return True class GraphicsContextMac(_macosx.GraphicsContext, GraphicsContextBase): diff --git a/lib/matplotlib/backends/backend_mixed.py b/lib/matplotlib/backends/backend_mixed.py index 4845e63b6e99..6de45ed2ed05 100644 --- a/lib/matplotlib/backends/backend_mixed.py +++ b/lib/matplotlib/backends/backend_mixed.py @@ -63,7 +63,7 @@ def __init__(self, figure, width, height, dpi, vector_renderer, draw_path_collection draw_quad_mesh draw_tex draw_text finalize flipy get_canvas_width_height get_image_magnification get_texmanager get_text_width_height_descent new_gc open_group - option_combine_images points_to_pixels strip_math + option_image_nocomposite points_to_pixels strip_math start_filter stop_filter draw_gouraud_triangle draw_gouraud_triangles option_scale_image _text2path _get_text_path_transform height width diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index 1a2d7240e288..b6113c4e74c9 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -1577,12 +1577,12 @@ def option_scale_image(self): """ return True - def option_combine_images(self): + def option_image_nocomposite(self): """ - return whether to combine multiple images on a set of axes into one - image + return whether to generate a composite image from multiple images on + a set of axes """ - return rcParams['image.combine_images'] + return not rcParams['image.composite_image'] def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None): self.check_gc(gc) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index ffac6229914d..6aa54ad1de42 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -452,12 +452,12 @@ def option_scale_image(self): """ return True - def option_combine_images(self): + def option_image_nocomposite(self): """ - return whether to combine multiple images on a set of axes into one - image + return whether to generate a composite image from multiple images on + a set of axes """ - return rcParams['image.combine_images'] + return not rcParams['image.composite_image'] def _get_image_h_w_bits_command(self, im): if im.is_grayscale: diff --git a/lib/matplotlib/backends/backend_svg.py b/lib/matplotlib/backends/backend_svg.py index f1ea9a52ef9d..160604ec95fe 100644 --- a/lib/matplotlib/backends/backend_svg.py +++ b/lib/matplotlib/backends/backend_svg.py @@ -527,15 +527,15 @@ def open_group(self, s, gid=None): def close_group(self, s): self.writer.end('g') - def option_combine_images(self): + def option_image_nocomposite(self): """ - if svg.image_noscale is True, combining multiple images into one is - prohibited + return whether to generate a composite image from multiple images on + a set of axes """ if rcParams['svg.image_noscale']: - return False + return True else: - return rcParams['image.combine_images'] + return not rcParams['image.composite_image'] def _convert_path(self, path, transform=None, clip=None, simplify=None): if clip: diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index 8d99f9a69de3..ded438031afd 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -1045,16 +1045,16 @@ def draw(self, renderer): # override the renderer default if self.suppressComposite # is not None - combine_images = renderer.option_combine_images() + not_composite = renderer.option_image_nocomposite() if self.suppressComposite is not None: - combine_images = not self.suppressComposite + not_composite = self.suppressComposite - if (len(self.images) <= 1 or not combine_images or + if (len(self.images) <= 1 or not_composite or not cbook.allequal([im.origin for im in self.images])): for a in self.images: dsu.append((a.get_zorder(), a, a.draw, [renderer])) else: - # make a combined image, blending alpha + # make a composite image blending alpha # list of (_image.Image, ox, oy) mag = renderer.get_image_magnification() ims = [(im.make_image(mag), im.ox, im.oy, im.get_alpha()) @@ -1067,7 +1067,7 @@ def draw(self, renderer): im.is_grayscale = False l, b, w, h = self.bbox.bounds - def draw_combined_image(): + def draw_composite(): gc = renderer.new_gc() gc.set_clip_rectangle(self.bbox) gc.set_clip_path(self.get_clip_path()) @@ -1075,7 +1075,7 @@ def draw_combined_image(): gc.restore() dsu.append((self.images[0].get_zorder(), self.images[0], - draw_combined_image, [])) + draw_composite, [])) # render the axes for a in self.axes: diff --git a/lib/matplotlib/rcsetup.py b/lib/matplotlib/rcsetup.py index 4c1e40bc2f98..9815d7547e54 100644 --- a/lib/matplotlib/rcsetup.py +++ b/lib/matplotlib/rcsetup.py @@ -595,9 +595,9 @@ def __call__(self, s): 'image.lut': [256, validate_int], # lookup table 'image.origin': ['upper', six.text_type], # lookup table 'image.resample': [False, validate_bool], - # Force vector graphics backends to combine all images on a set of axes - # into a single image - 'image.combine_images': [True, validate_bool], + # Specify whether vector graphics backends will combine all images on a + # set of axes into a single composite image + 'image.composite_image': [True, validate_bool], # contour props 'contour.negative_linestyle': ['dashed', diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_combine_alpha.pdf b/lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.pdf similarity index 100% rename from lib/matplotlib/tests/baseline_images/test_image/image_combine_alpha.pdf rename to lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.pdf diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_combine_alpha.png b/lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.png similarity index 100% rename from lib/matplotlib/tests/baseline_images/test_image/image_combine_alpha.png rename to lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.png diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_combine_alpha.svg b/lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.svg similarity index 100% rename from lib/matplotlib/tests/baseline_images/test_image/image_combine_alpha.svg rename to lib/matplotlib/tests/baseline_images/test_image/image_composite_alpha.svg diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_combine_background.pdf b/lib/matplotlib/tests/baseline_images/test_image/image_composite_background.pdf similarity index 100% rename from lib/matplotlib/tests/baseline_images/test_image/image_combine_background.pdf rename to lib/matplotlib/tests/baseline_images/test_image/image_composite_background.pdf diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_combine_background.png b/lib/matplotlib/tests/baseline_images/test_image/image_composite_background.png similarity index 100% rename from lib/matplotlib/tests/baseline_images/test_image/image_combine_background.png rename to lib/matplotlib/tests/baseline_images/test_image/image_composite_background.png diff --git a/lib/matplotlib/tests/baseline_images/test_image/image_combine_background.svg b/lib/matplotlib/tests/baseline_images/test_image/image_composite_background.svg similarity index 100% rename from lib/matplotlib/tests/baseline_images/test_image/image_combine_background.svg rename to lib/matplotlib/tests/baseline_images/test_image/image_composite_background.svg diff --git a/lib/matplotlib/tests/test_backend_pdf.py b/lib/matplotlib/tests/test_backend_pdf.py index 8311be430cf9..6ba1e4a5c36e 100644 --- a/lib/matplotlib/tests/test_backend_pdf.py +++ b/lib/matplotlib/tests/test_backend_pdf.py @@ -89,9 +89,9 @@ def test_multipage_keep_empty(): @cleanup -def test_combine_images(): +def test_composite_image(): #Test that figures can be saved with and without combining multiple images - #(on a single set of axes) into a single image. + #(on a single set of axes) into a single composite image. X, Y = np.meshgrid(np.arange(-5, 5, 1), np.arange(-5, 5, 1)) Z = np.sin(Y ** 2) fig = plt.figure() @@ -99,11 +99,11 @@ def test_combine_images(): ax.set_xlim(0, 3) ax.imshow(Z, extent=[0, 1, 0, 1]) ax.imshow(Z[::-1], extent=[2, 3, 0, 1]) - plt.rcParams['image.combine_images'] = True + plt.rcParams['image.composite_image'] = True with PdfPages(io.BytesIO()) as pdf: fig.savefig(pdf, format="pdf") assert len(pdf._file.images.keys()) == 1 - plt.rcParams['image.combine_images'] = False + plt.rcParams['image.composite_image'] = False with PdfPages(io.BytesIO()) as pdf: fig.savefig(pdf, format="pdf") assert len(pdf._file.images.keys()) == 2 diff --git a/lib/matplotlib/tests/test_backend_ps.py b/lib/matplotlib/tests/test_backend_ps.py index 09e73db939ff..1f32c1fa2572 100644 --- a/lib/matplotlib/tests/test_backend_ps.py +++ b/lib/matplotlib/tests/test_backend_ps.py @@ -87,9 +87,9 @@ def test_savefig_to_stringio_with_usetex_eps(): @cleanup -def test_combine_images(): +def test_composite_image(): #Test that figures can be saved with and without combining multiple images - #(on a single set of axes) into a single image. + #(on a single set of axes) into a single composite image. X, Y = np.meshgrid(np.arange(-5, 5, 1), np.arange(-5, 5, 1)) Z = np.sin(Y ** 2) fig = plt.figure() @@ -97,13 +97,13 @@ def test_combine_images(): ax.set_xlim(0, 3) ax.imshow(Z, extent=[0, 1, 0, 1]) ax.imshow(Z[::-1], extent=[2, 3, 0, 1]) - plt.rcParams['image.combine_images'] = True + plt.rcParams['image.composite_image'] = True with io.BytesIO() as ps: fig.savefig(ps, format="ps") ps.seek(0) buff = ps.read() assert buff.count(six.b(' colorimage')) == 1 - plt.rcParams['image.combine_images'] = False + plt.rcParams['image.composite_image'] = False with io.BytesIO() as ps: fig.savefig(ps, format="ps") ps.seek(0) diff --git a/lib/matplotlib/tests/test_backend_svg.py b/lib/matplotlib/tests/test_backend_svg.py index 5de764d395f4..3dde9350bc5f 100644 --- a/lib/matplotlib/tests/test_backend_svg.py +++ b/lib/matplotlib/tests/test_backend_svg.py @@ -56,9 +56,9 @@ def test_noscale(): @cleanup -def test_combine_images(): +def test_composite_images(): #Test that figures can be saved with and without combining multiple images - #(on a single set of axes) into a single image. + #(on a single set of axes) into a single composite image. X, Y = np.meshgrid(np.arange(-5, 5, 1), np.arange(-5, 5, 1)) Z = np.sin(Y ** 2) fig = plt.figure() @@ -66,13 +66,13 @@ def test_combine_images(): ax.set_xlim(0, 3) ax.imshow(Z, extent=[0, 1, 0, 1]) ax.imshow(Z[::-1], extent=[2, 3, 0, 1]) - plt.rcParams['image.combine_images'] = True + plt.rcParams['image.composite_image'] = True with BytesIO() as svg: fig.savefig(svg, format="svg") svg.seek(0) buff = svg.read() assert buff.count(six.b(' Date: Sun, 1 Mar 2015 21:07:39 -0700 Subject: [PATCH 3/8] Fixed an indentation issue with 'matplotlibrc.template' and reverted a comment in 'test_image.test_image_composite_alpha()' to the 'composite_image' terminology. --- lib/matplotlib/tests/test_image.py | 2 +- matplotlibrc.template | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/tests/test_image.py b/lib/matplotlib/tests/test_image.py index 8aac600cb20f..89338d33fdad 100644 --- a/lib/matplotlib/tests/test_image.py +++ b/lib/matplotlib/tests/test_image.py @@ -262,7 +262,7 @@ def test_image_composite_background(): def test_image_composite_alpha(): """ Tests that the alpha value is recognized and correctly applied in the - process of combining images together. + process of compositing images together. """ fig = plt.figure() ax = fig.add_subplot(111) diff --git a/matplotlibrc.template b/matplotlibrc.template index fce9b2d9cb42..d27b78a7bcd5 100644 --- a/matplotlibrc.template +++ b/matplotlibrc.template @@ -359,7 +359,7 @@ backend : %(backend)s #image.origin : upper # lower | upper #image.resample : False #image.composite_image : True # When True, all the images on a set of axes are - # combined into a single composite image before + # combined into a single composite image before # saving a figure as a vector graphics file, # such as a PDF. From e446485e7e6dfb169dc3aca50a9773843c411039 Mon Sep 17 00:00:00 2001 From: Benjamin Reedlunn Date: Sun, 1 Mar 2015 21:24:25 -0700 Subject: [PATCH 4/8] Fixed a PEP8 issue with backend_pdf.py --- lib/matplotlib/backends/backend_pdf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/backends/backend_pdf.py b/lib/matplotlib/backends/backend_pdf.py index b6113c4e74c9..3e23a758f2cb 100644 --- a/lib/matplotlib/backends/backend_pdf.py +++ b/lib/matplotlib/backends/backend_pdf.py @@ -1579,7 +1579,7 @@ def option_scale_image(self): def option_image_nocomposite(self): """ - return whether to generate a composite image from multiple images on + return whether to generate a composite image from multiple images on a set of axes """ return not rcParams['image.composite_image'] From 9dfa625a81af9550df0212de0c40df2f4ce5d8b4 Mon Sep 17 00:00:00 2001 From: Benjamin Reedlunn Date: Mon, 2 Mar 2015 19:47:33 -0700 Subject: [PATCH 5/8] Updated 'whats new.rst' to make users aware of the new rcParam['image.composite_image'] --- doc/users/whats_new.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/users/whats_new.rst b/doc/users/whats_new.rst index f3dfbb720e89..afd0cde5e62c 100644 --- a/doc/users/whats_new.rst +++ b/doc/users/whats_new.rst @@ -75,6 +75,14 @@ directive - ``close-figs`` - that closes any previous figure windows before creating the plots. This can help avoid some surprising duplicates of plots when using ``plot_directive``. +Configuration (rcParams) +------------------------ + +``image.composite_image`` added +``````````````````````````````` +Controls whether vector graphics backends (i.e. PDF, PS, and SVG) combine +multiple images on a set of axes into a single composite image. + .. _whats-new-1-4: new in matplotlib-1.4 From 8b6d7c3a22dba7108de63b24b749d01a857f6502 Mon Sep 17 00:00:00 2001 From: Benjamin Reedlunn Date: Mon, 2 Mar 2015 20:00:20 -0700 Subject: [PATCH 6/8] Updated 'whats_new.rst' with a little bit more explanation of why you might use the 'image.composite_image' option. --- doc/users/whats_new.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/users/whats_new.rst b/doc/users/whats_new.rst index afd0cde5e62c..84288466fd0e 100644 --- a/doc/users/whats_new.rst +++ b/doc/users/whats_new.rst @@ -81,7 +81,9 @@ Configuration (rcParams) ``image.composite_image`` added ``````````````````````````````` Controls whether vector graphics backends (i.e. PDF, PS, and SVG) combine -multiple images on a set of axes into a single composite image. +multiple images on a set of axes into a single composite image. Saving each +image individually can be useful if you wish to edit a matplotlib generated +vector graphics file in Inkscape or other programs. .. _whats-new-1-4: From 4f2a61d2fc2e62512922c776232de922bcbc95e8 Mon Sep 17 00:00:00 2001 From: Benjamin Reedlunn Date: Mon, 2 Mar 2015 20:02:53 -0700 Subject: [PATCH 7/8] Updated 'whats_new.rst' with a slightly better explanation of why you might use the 'image.composite_image' option. --- doc/users/whats_new.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/users/whats_new.rst b/doc/users/whats_new.rst index 84288466fd0e..5b3168ebac4e 100644 --- a/doc/users/whats_new.rst +++ b/doc/users/whats_new.rst @@ -82,8 +82,8 @@ Configuration (rcParams) ``````````````````````````````` Controls whether vector graphics backends (i.e. PDF, PS, and SVG) combine multiple images on a set of axes into a single composite image. Saving each -image individually can be useful if you wish to edit a matplotlib generated -vector graphics file in Inkscape or other programs. +image individually can be useful if you generate vector graphics files in +matplotlib and then edit the files further in Inkscape or other programs. .. _whats-new-1-4: From ec76724790628930a43a858f785a6fb55489a2a4 Mon Sep 17 00:00:00 2001 From: Benjamin Reedlunn Date: Wed, 4 Mar 2015 20:41:13 -0700 Subject: [PATCH 8/8] Reverted a comment from 'option_combine_images' to 'option_image_nocomposite'. Also moved the whats_new addition into a separate file. --- doc/users/whats_new.rst | 10 ---------- doc/users/whats_new/rcparams.rst | 13 +++++++------ lib/matplotlib/figure.py | 2 +- 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/doc/users/whats_new.rst b/doc/users/whats_new.rst index 5b3168ebac4e..f3dfbb720e89 100644 --- a/doc/users/whats_new.rst +++ b/doc/users/whats_new.rst @@ -75,16 +75,6 @@ directive - ``close-figs`` - that closes any previous figure windows before creating the plots. This can help avoid some surprising duplicates of plots when using ``plot_directive``. -Configuration (rcParams) ------------------------- - -``image.composite_image`` added -``````````````````````````````` -Controls whether vector graphics backends (i.e. PDF, PS, and SVG) combine -multiple images on a set of axes into a single composite image. Saving each -image individually can be useful if you generate vector graphics files in -matplotlib and then edit the files further in Inkscape or other programs. - .. _whats-new-1-4: new in matplotlib-1.4 diff --git a/doc/users/whats_new/rcparams.rst b/doc/users/whats_new/rcparams.rst index 3624fb7b11c4..d3b62bf40518 100644 --- a/doc/users/whats_new/rcparams.rst +++ b/doc/users/whats_new/rcparams.rst @@ -1,20 +1,21 @@ Added "legend.framealpha" key to rcParams ````````````````````````````````````````` - Added a key and the corresponding logic to control the default transparency of legend frames. This feature was written into the docstring of axes.legend(), but not yet implemented. - Added "figure.titlesize" and "figure.titleweight" keys to rcParams `````````````````````````````````````````````````````````````````` - Two new keys were added to rcParams to control the default font size and weight used by the figure title (as emitted by ``pyplot.suptitle()``). - - Added "legend.facecolor" and "legend.edgecolor" keys to rcParams ```````````````````````````````````````````````````````````````` - The new keys control colors (background and edge) of legend patches. + +``image.composite_image`` added to rcParams +``````````````````````````````````````````` +Controls whether vector graphics backends (i.e. PDF, PS, and SVG) combine +multiple images on a set of axes into a single composite image. Saving each +image individually can be useful if you generate vector graphics files in +matplotlib and then edit the files further in Inkscape or other programs. diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index ded438031afd..986870c78140 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -249,7 +249,7 @@ class Figure(Artist): *suppressComposite* For multiple figure images, the figure will make composite - images depending on the renderer option_combine_images + images depending on the renderer option_image_nocomposite function. If suppressComposite is True|False, this will override the renderer. """