From 014f32d0ed546a9f282d0daa6c7e354bf2e4d0e2 Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Tue, 3 Mar 2015 18:59:09 -0500 Subject: [PATCH 1/3] Close clipped paths --- lib/matplotlib/tests/test_colorbar.py | 28 +++++++++++++++++++++++++ lib/matplotlib/tests/test_transforms.py | 2 +- src/path_converters.h | 9 ++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/matplotlib/tests/test_colorbar.py b/lib/matplotlib/tests/test_colorbar.py index 8cd60e18dd52..b233bfc51770 100644 --- a/lib/matplotlib/tests/test_colorbar.py +++ b/lib/matplotlib/tests/test_colorbar.py @@ -11,6 +11,7 @@ from matplotlib import rcParams from matplotlib.colors import BoundaryNorm from matplotlib.cm import get_cmap +from matplotlib import cm from matplotlib.colorbar import ColorbarBase @@ -253,6 +254,33 @@ def test_colorbarbase(): ColorbarBase(ax, plt.cm.bone) +@image_comparison( + baseline_images=['colorbar_closed_patch'], + remove_text=True) +def test_colorbar_closed_patch(): + fig = plt.figure(figsize=(8,6)) + ax1 = fig.add_axes([0.05, 0.85, 0.9, 0.1]) + ax2 = fig.add_axes([0.05, 0.65, 0.9, 0.1]) + ax3 = fig.add_axes([0.05, 0.45, 0.9, 0.1]) + ax4 = fig.add_axes([0.05, 0.25, 0.9, 0.1]) + ax5 = fig.add_axes([0.05, 0.05, 0.9, 0.1]) + + cmap = cm.jet + cmap.set_under('w') + cmap.set_over('w') + + im = ax1.pcolormesh(np.linspace(0,10,16).reshape((4,4))) + + plt.colorbar(im,cax=ax2,cmap=cmap,orientation='horizontal', + extend='both',extendfrac=0.5) + plt.colorbar(im,cax=ax3,cmap=cmap,orientation='horizontal', + extend='both',) + plt.colorbar(im,cax=ax4,cmap=cmap,orientation='horizontal', + extend='both',extendrect=True) + plt.colorbar(im,cax=ax5,cmap=cmap,orientation='horizontal', + extend='neither') + + if __name__ == '__main__': import nose nose.runmodule(argv=['-s', '--with-doctest'], exit=False) diff --git a/lib/matplotlib/tests/test_transforms.py b/lib/matplotlib/tests/test_transforms.py index c138b5937db9..3e71a5e63414 100644 --- a/lib/matplotlib/tests/test_transforms.py +++ b/lib/matplotlib/tests/test_transforms.py @@ -206,7 +206,7 @@ def test_clipping_of_log(): # Because y coordinate -99 is outside the clip zone, the first # line segment is effectively removed. That means that the closepoly # operation must be replaced by a move to the first point. - assert np.allclose(tcodes, [ M, M, L, L, L ]) + assert np.allclose(tcodes, [ M, M, L, L, L, C ]) class NonAffineForTest(mtrans.Transform): diff --git a/src/path_converters.h b/src/path_converters.h index 1e5ac990df6d..77557720f054 100644 --- a/src/path_converters.h +++ b/src/path_converters.h @@ -253,6 +253,7 @@ class PathClipper double m_nextX; double m_nextY; bool m_has_next; + bool m_end_poly; double m_initX; double m_initY; bool m_has_init; @@ -265,6 +266,7 @@ class PathClipper m_cliprect(-1.0, -1.0, width + 1.0, height + 1.0), m_moveto(true), m_has_next(false), + m_end_poly(false), m_has_init(false), m_broke_path(false) { @@ -277,6 +279,7 @@ class PathClipper m_cliprect(rect), m_moveto(true), m_has_next(false), + m_end_poly(false), m_has_init(false), m_broke_path(false) { @@ -300,6 +303,11 @@ class PathClipper if (m_do_clipping) { /* This is the slow path where we actually do clipping */ + if (m_end_poly) { + m_end_poly = false; + return (agg::path_cmd_end_poly | agg::path_flags_close); + } + if (m_has_next) { m_has_next = false; *x = m_nextX; @@ -313,6 +321,7 @@ class PathClipper *x = m_initX; *y = m_initY; code = agg::path_cmd_line_to; + m_end_poly = true; } else { continue; } From 2f932e10995a2b577d7d410ffbee045611a422cf Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Wed, 4 Mar 2015 14:54:54 -0500 Subject: [PATCH 2/3] Add test data --- .../test_colorbar/colorbar_closed_patch.pdf | Bin 0 -> 2415 bytes .../test_colorbar/colorbar_closed_patch.png | Bin 0 -> 9294 bytes .../test_colorbar/colorbar_closed_patch.svg | 660 ++++++++++++++++++ lib/matplotlib/tests/test_colorbar.py | 2 +- 4 files changed, 661 insertions(+), 1 deletion(-) create mode 100644 lib/matplotlib/tests/baseline_images/test_colorbar/colorbar_closed_patch.pdf create mode 100644 lib/matplotlib/tests/baseline_images/test_colorbar/colorbar_closed_patch.png create mode 100644 lib/matplotlib/tests/baseline_images/test_colorbar/colorbar_closed_patch.svg diff --git a/lib/matplotlib/tests/baseline_images/test_colorbar/colorbar_closed_patch.pdf b/lib/matplotlib/tests/baseline_images/test_colorbar/colorbar_closed_patch.pdf new file mode 100644 index 0000000000000000000000000000000000000000..81271ec29c813d2ab4c99fab4ffb07adb75d5b33 GIT binary patch literal 2415 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/test_colorbar.py b/lib/matplotlib/tests/test_colorbar.py index b233bfc51770..ef5c113630ec 100644 --- a/lib/matplotlib/tests/test_colorbar.py +++ b/lib/matplotlib/tests/test_colorbar.py @@ -260,7 +260,7 @@ def test_colorbarbase(): def test_colorbar_closed_patch(): fig = plt.figure(figsize=(8,6)) ax1 = fig.add_axes([0.05, 0.85, 0.9, 0.1]) - ax2 = fig.add_axes([0.05, 0.65, 0.9, 0.1]) + ax2 = fig.add_axes([0.1, 0.65, 0.75, 0.1]) ax3 = fig.add_axes([0.05, 0.45, 0.9, 0.1]) ax4 = fig.add_axes([0.05, 0.25, 0.9, 0.1]) ax5 = fig.add_axes([0.05, 0.05, 0.9, 0.1]) From 3b63c19d6b51353ffaab4305f624be0e7677f95e Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Wed, 4 Mar 2015 14:55:10 -0500 Subject: [PATCH 3/3] Disable miter limit in SVG, PS and Agg backends --- lib/matplotlib/backends/backend_ps.py | 4 ++++ lib/matplotlib/backends/backend_svg.py | 5 ++++- lib/matplotlib/tests/test_colorbar.py | 29 +++++++++++++------------- src/_backend_agg.h | 3 +++ 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/lib/matplotlib/backends/backend_ps.py b/lib/matplotlib/backends/backend_ps.py index 1474d95d9c26..ae2abcc23bb7 100644 --- a/lib/matplotlib/backends/backend_ps.py +++ b/lib/matplotlib/backends/backend_ps.py @@ -1189,6 +1189,8 @@ def print_figure_impl(): print("%s translate"%_nums_to_str(xo, yo), file=fh) if rotation: print("%d rotate"%rotation, file=fh) print("%s clipbox"%_nums_to_str(width*72, height*72, 0, 0), file=fh) + # Disable any sort of miter limit + print("%s setmiterlimit" % 100000, file=fh) # write the figure content = self._pswriter.getvalue() @@ -1338,6 +1340,8 @@ def write(self, *kl, **kwargs): #print >>fh, "gsave" print("%s translate"%_nums_to_str(xo, yo), file=fh) print("%s clipbox"%_nums_to_str(width*72, height*72, 0, 0), file=fh) + # Disable any sort of miter limit + print("%d setmiterlimit" % 100000, file=fh) # write the figure print(self._pswriter.getvalue(), file=fh) diff --git a/lib/matplotlib/backends/backend_svg.py b/lib/matplotlib/backends/backend_svg.py index 865acf66620e..0531fec27364 100644 --- a/lib/matplotlib/backends/backend_svg.py +++ b/lib/matplotlib/backends/backend_svg.py @@ -297,7 +297,10 @@ def _write_default_style(self): writer = self.writer default_style = generate_css({ 'stroke-linejoin': 'round', - 'stroke-linecap': 'butt'}) + 'stroke-linecap': 'butt', + # Disable the miter limit. 100000 seems to be close to + # the maximum that renderers support before breaking. + 'stroke-miterlimit': '100000'}) writer.start('defs') writer.start('style', type='text/css') writer.data('*{%s}\n' % default_style) diff --git a/lib/matplotlib/tests/test_colorbar.py b/lib/matplotlib/tests/test_colorbar.py index ef5c113630ec..f415a8aa9808 100644 --- a/lib/matplotlib/tests/test_colorbar.py +++ b/lib/matplotlib/tests/test_colorbar.py @@ -6,6 +6,7 @@ import numpy as np from numpy import ma import matplotlib +from matplotlib import rc_context from matplotlib.testing.decorators import image_comparison, cleanup import matplotlib.pyplot as plt from matplotlib import rcParams @@ -258,27 +259,27 @@ def test_colorbarbase(): baseline_images=['colorbar_closed_patch'], remove_text=True) def test_colorbar_closed_patch(): - fig = plt.figure(figsize=(8,6)) + fig = plt.figure(figsize=(8, 6)) ax1 = fig.add_axes([0.05, 0.85, 0.9, 0.1]) ax2 = fig.add_axes([0.1, 0.65, 0.75, 0.1]) ax3 = fig.add_axes([0.05, 0.45, 0.9, 0.1]) ax4 = fig.add_axes([0.05, 0.25, 0.9, 0.1]) ax5 = fig.add_axes([0.05, 0.05, 0.9, 0.1]) - cmap = cm.jet - cmap.set_under('w') - cmap.set_over('w') - - im = ax1.pcolormesh(np.linspace(0,10,16).reshape((4,4))) + cmap = get_cmap("RdBu", lut=5) - plt.colorbar(im,cax=ax2,cmap=cmap,orientation='horizontal', - extend='both',extendfrac=0.5) - plt.colorbar(im,cax=ax3,cmap=cmap,orientation='horizontal', - extend='both',) - plt.colorbar(im,cax=ax4,cmap=cmap,orientation='horizontal', - extend='both',extendrect=True) - plt.colorbar(im,cax=ax5,cmap=cmap,orientation='horizontal', - extend='neither') + im = ax1.pcolormesh(np.linspace(0, 10, 16).reshape((4, 4)), cmap=cmap) + values = np.linspace(0, 10, 5) + + with rc_context({'axes.linewidth': 16}): + plt.colorbar(im, cax=ax2, cmap=cmap, orientation='horizontal', + extend='both', extendfrac=0.5, values=values) + plt.colorbar(im, cax=ax3, cmap=cmap, orientation='horizontal', + extend='both', values=values) + plt.colorbar(im, cax=ax4, cmap=cmap, orientation='horizontal', + extend='both', extendrect=True, values=values) + plt.colorbar(im, cax=ax5, cmap=cmap, orientation='horizontal', + extend='neither', values=values) if __name__ == '__main__': diff --git a/src/_backend_agg.h b/src/_backend_agg.h index 8d454a1faaa6..798905ebcac3 100644 --- a/src/_backend_agg.h +++ b/src/_backend_agg.h @@ -417,6 +417,7 @@ RendererAgg::_draw_path(path_t &path, bool has_clippath, const facepair_t &face, stroke.width(points_to_pixels(gc.linewidth)); stroke.line_cap(gc.cap); stroke.line_join(gc.join); + stroke.miter_limit(points_to_pixels(gc.linewidth)); theRasterizer.add_path(stroke); } else { dash_t dash(path); @@ -425,6 +426,7 @@ RendererAgg::_draw_path(path_t &path, bool has_clippath, const facepair_t &face, stroke.line_cap(gc.cap); stroke.line_join(gc.join); stroke.width(linewidth); + stroke.miter_limit(points_to_pixels(gc.linewidth)); theRasterizer.add_path(stroke); } @@ -564,6 +566,7 @@ inline void RendererAgg::draw_markers(GCAgg &gc, stroke.width(points_to_pixels(gc.linewidth)); stroke.line_cap(gc.cap); stroke.line_join(gc.join); + stroke.miter_limit(points_to_pixels(gc.linewidth)); theRasterizer.reset(); theRasterizer.add_path(stroke); agg::render_scanlines(theRasterizer, slineP8, scanlines);