From 9fb4f9bba510f42b376b8e835c453d7ba96c89b1 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sat, 14 Jan 2017 21:15:48 -0500 Subject: [PATCH 1/3] MNT: copy unscaled dash data in update_from As part of scaling dashes with linewidth, unscaled versions of the dash pattern are now tracked. Make sure we copy these as well. --- lib/matplotlib/collections.py | 1 + lib/matplotlib/lines.py | 2 ++ lib/matplotlib/patches.py | 6 +++--- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index 59971926213b..4da0d66663e5 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -788,6 +788,7 @@ def update_from(self, other): self._facecolors = other._facecolors self._linewidths = other._linewidths self._linestyles = other._linestyles + self._us_linestyles = other._us_linestyles self._pickradius = other._pickradius self._hatch = other._hatch diff --git a/lib/matplotlib/lines.py b/lib/matplotlib/lines.py index e29bda464081..57634cf2964c 100644 --- a/lib/matplotlib/lines.py +++ b/lib/matplotlib/lines.py @@ -1319,7 +1319,9 @@ def update_from(self, other): self._markeredgecolor = other._markeredgecolor self._markeredgewidth = other._markeredgewidth self._dashSeq = other._dashSeq + self._us_dashSeq = other._us_dashSeq self._dashOffset = other._dashOffset + self._us_dashOffset = other._us_dashOffset self._dashcapstyle = other._dashcapstyle self._dashjoinstyle = other._dashjoinstyle self._solidcapstyle = other._solidcapstyle diff --git a/lib/matplotlib/patches.py b/lib/matplotlib/patches.py index fd4b745e1f2d..05be96ee9e21 100644 --- a/lib/matplotlib/patches.py +++ b/lib/matplotlib/patches.py @@ -199,9 +199,9 @@ def update_from(self, other): self._facecolor = other._facecolor self._fill = other._fill self._hatch = other._hatch - self._linewidth = other._linewidth - # Use setters, getters where we need the extra work they do. - self.set_linestyle(other._linestyle) # also sets dash properties + # copy the unscaled dash pattern + self._us_dashes = other._us_dashes + self.set_linewidth(other._linewidth) # also sets dash properties self.set_transform(other.get_data_transform()) def get_extents(self): From 9893d4fa2e849f2574996bbd72738d9fb9a0b65f Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sat, 14 Jan 2017 21:22:41 -0500 Subject: [PATCH 2/3] FIX: pull the unscaled dashes from the line collection To prevent double-scaling of the pattern in the legend Closes #7814 --- lib/matplotlib/legend_handler.py | 5 ++--- lib/matplotlib/tests/test_legend.py | 25 +++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/lib/matplotlib/legend_handler.py b/lib/matplotlib/legend_handler.py index fccf31d4b414..1cc81fa0474a 100644 --- a/lib/matplotlib/legend_handler.py +++ b/lib/matplotlib/legend_handler.py @@ -266,12 +266,11 @@ def get_numpoints(self, legend): def _default_update_prop(self, legend_handle, orig_handle): lw = orig_handle.get_linewidths()[0] - dashes = orig_handle.get_dashes()[0] + dashes = orig_handle._us_linestyles[0] color = orig_handle.get_colors()[0] legend_handle.set_color(color) + legend_handle.set_linestyle(dashes) legend_handle.set_linewidth(lw) - if dashes[0] is not None: # dashed line - legend_handle.set_dashes(dashes[1]) def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans): diff --git a/lib/matplotlib/tests/test_legend.py b/lib/matplotlib/tests/test_legend.py index 8e6708b3489c..10b5a0da2940 100644 --- a/lib/matplotlib/tests/test_legend.py +++ b/lib/matplotlib/tests/test_legend.py @@ -17,7 +17,7 @@ import matplotlib as mpl import matplotlib.patches as mpatches import matplotlib.transforms as mtrans - +import matplotlib.collections as mc @image_comparison(baseline_images=['legend_auto1'], remove_text=True) def test_legend_auto1(): @@ -296,7 +296,28 @@ def test_not_covering_scatter_transform(): plt.legend(['foo', 'bar'], loc='best') +@cleanup +def test_linecollection_scaled_dashes(): + lines1 = [[(0, .5), (.5, 1)], [(.3, .6), (.2, .2)]] + lines2 = [[[0.7, .2], [.8, .4]], [[.5, .7], [.6, .1]]] + lines3 = [[[0.6, .2], [.8, .4]], [[.5, .7], [.1, .1]]] + lc1 = mc.LineCollection(lines1, linestyles="--", lw=3) + lc2 = mc.LineCollection(lines2, linestyles="-.") + lc3 = mc.LineCollection(lines3, linestyles=":", lw=.5) + + fig, ax = plt.subplots() + ax.add_collection(lc1) + ax.add_collection(lc2) + ax.add_collection(lc3) + + leg = ax.legend([lc1, lc2, lc3], ["line1", "line2", 'line 3']) + h1, h2, h3 = leg.legendHandles + + for oh, lh in zip((lc1, lc2, lc3), (h1, h2, h3)): + assert oh.get_linestyles()[0][1] == lh._dashSeq + assert oh.get_linestyles()[0][0] == lh._dashOffset + + if __name__ == '__main__': import nose nose.runmodule(argv=['-s', '--with-doctest'], exit=False) - From 9a75feba7ff054ee3d68a922934d40ca525522da Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sun, 15 Jan 2017 13:18:37 -0500 Subject: [PATCH 3/3] TST: tweak imports / whitespace in tests --- lib/matplotlib/tests/test_coding_standards.py | 1 - lib/matplotlib/tests/test_legend.py | 25 ++++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/matplotlib/tests/test_coding_standards.py b/lib/matplotlib/tests/test_coding_standards.py index 9919c0d985fc..a0ccdfa22bf2 100644 --- a/lib/matplotlib/tests/test_coding_standards.py +++ b/lib/matplotlib/tests/test_coding_standards.py @@ -207,7 +207,6 @@ def test_pep8_conformance_installed_files(): 'tests/test_delaunay.py', 'tests/test_dviread.py', 'tests/test_image.py', - 'tests/test_legend.py', 'tests/test_lines.py', 'tests/test_mathtext.py', 'tests/test_rcparams.py', diff --git a/lib/matplotlib/tests/test_legend.py b/lib/matplotlib/tests/test_legend.py index 10b5a0da2940..052e4959c968 100644 --- a/lib/matplotlib/tests/test_legend.py +++ b/lib/matplotlib/tests/test_legend.py @@ -12,12 +12,11 @@ import numpy as np from matplotlib.testing.decorators import image_comparison, cleanup -from matplotlib.cbook import MatplotlibDeprecationWarning import matplotlib.pyplot as plt import matplotlib as mpl -import matplotlib.patches as mpatches import matplotlib.transforms as mtrans -import matplotlib.collections as mc +import matplotlib.collections as mcollections + @image_comparison(baseline_images=['legend_auto1'], remove_text=True) def test_legend_auto1(): @@ -110,7 +109,8 @@ def test_fancy(): plt.subplot(121) plt.scatter(list(xrange(10)), list(xrange(10, 0, -1)), label='XX\nXX') plt.plot([5] * 10, 'o--', label='XX') - plt.errorbar(list(xrange(10)), list(xrange(10)), xerr=0.5, yerr=0.5, label='XX') + plt.errorbar(list(xrange(10)), list(xrange(10)), xerr=0.5, + yerr=0.5, label='XX') plt.legend(loc="center left", bbox_to_anchor=[1.0, 0.5], ncol=2, shadow=True, title="My legend", numpoints=1) @@ -123,7 +123,8 @@ def test_framealpha(): plt.legend(framealpha=0.5) -@image_comparison(baseline_images=['scatter_rc3', 'scatter_rc1'], remove_text=True) +@image_comparison(baseline_images=['scatter_rc3', 'scatter_rc1'], + remove_text=True) def test_rc(): # using subplot triggers some offsetbox functionality untested elsewhere fig = plt.figure() @@ -221,8 +222,8 @@ def test_warn_args_kwargs(self): ax.legend((lnc, lns), labels=('a', 'b')) warn.assert_called_with("You have mixed positional and keyword " - "arguments, some input will be " - "discarded.") + "arguments, some input will be " + "discarded.") @image_comparison(baseline_images=['legend_stackplot'], extensions=['png']) @@ -273,10 +274,10 @@ def test_nanscatter(): @image_comparison(baseline_images=['not_covering_scatter'], extensions=['png']) def test_not_covering_scatter(): - colors = ['b','g','r'] + colors = ['b', 'g', 'r'] for n in range(3): - plt.scatter([n,], [n,], color=colors[n]) + plt.scatter([n], [n], color=colors[n]) plt.legend(['foo', 'foo', 'foo'], loc='best') plt.gca().set_xlim(-0.5, 2.2) @@ -301,9 +302,9 @@ def test_linecollection_scaled_dashes(): lines1 = [[(0, .5), (.5, 1)], [(.3, .6), (.2, .2)]] lines2 = [[[0.7, .2], [.8, .4]], [[.5, .7], [.6, .1]]] lines3 = [[[0.6, .2], [.8, .4]], [[.5, .7], [.1, .1]]] - lc1 = mc.LineCollection(lines1, linestyles="--", lw=3) - lc2 = mc.LineCollection(lines2, linestyles="-.") - lc3 = mc.LineCollection(lines3, linestyles=":", lw=.5) + lc1 = mcollections.LineCollection(lines1, linestyles="--", lw=3) + lc2 = mcollections.LineCollection(lines2, linestyles="-.") + lc3 = mcollections.LineCollection(lines3, linestyles=":", lw=.5) fig, ax = plt.subplots() ax.add_collection(lc1)