From 283f358877a8ffbce7d05f16369beb63a4e73e66 Mon Sep 17 00:00:00 2001 From: Brian Mattern Date: Wed, 27 Mar 2013 20:26:44 -0700 Subject: [PATCH 1/8] Fix manual contour label positions on sparse contours Prior to this, contour labels were positioned at the nearest contour vertex, which in some cases (e.g., straight contours) could be quite distant from the desired location. This centers the label on the closest point on contour itself (using linear interpolation between vertices). --- lib/matplotlib/contour.py | 78 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 6 deletions(-) diff --git a/lib/matplotlib/contour.py b/lib/matplotlib/contour.py index aa7cc0a6a4a8..fdf0bb37edb3 100644 --- a/lib/matplotlib/contour.py +++ b/lib/matplotlib/contour.py @@ -572,6 +572,18 @@ def add_label_near(self, x, y, inline=True, inline_spacing=5, conmin, segmin, imin, xmin, ymin = self.find_nearest_contour( x, y, self.labelIndiceList)[:5] + # The calc_label_rot_and_inline routine requires that (xmin,ymin) + # be a vertex in the path. So, if it isn't, add a vertex here + paths = self.collections[conmin].get_paths() + lc = paths[segmin].vertices + if transform: + xcmin = transform.inverted().transform([xmin,ymin]) + else: + xcmin = np.array([xmin,ymin]) + if not np.allclose(xcmin, lc[imin]): + lc = np.r_[lc[:imin], np.array(xcmin)[None,:], lc[imin:]] + paths[segmin] = mpath.Path(lc) + # Get index of nearest level in subset of levels used for labeling lmin = self.labelIndiceList.index(conmin) @@ -673,6 +685,59 @@ def labels(self, inline, inline_spacing): del paths[:] paths.extend(additions) +def _find_closest_point_on_leg(p1, p2, p0): + '''find closest point to p0 on line segment connecting p1 and p2''' + + # handle degenerate case + if np.all(p2 == p1): + d = np.sum((p0 - p1)**2) + return d, p1 + + d21 = p2 - p1 + d01 = p0 - p1 + + # project on to line segment to find closest point + proj = np.dot(d01, d21) / np.dot(d21, d21) + if proj < 0: proj = 0 + if proj > 1: proj = 1 + pc = p1 + proj * d21 + + # find squared distance + d = np.sum((pc-p0)**2) + + return d, pc + +def _find_closest_point_on_path(lc, point): + ''' + lc: coordinates of vertices + point: coordinates of test point + ''' + + # find index of closest vertex for this segment + ds = np.sum((lc - point[None,:])**2, 1) + imin = np.argmin(ds) + + dmin = 1e10 + xcmin = None + legmin = (None,None) + + closed = mlab.is_closed_polygon(lc) + + # build list of legs before and after this vertex + legs = [] + if imin > 0 or closed: + legs.append(((imin-1)%len(lc),imin)) + if imin < len(lc) - 1 or closed: + legs.append((imin,(imin+1)%len(lc))) + + for leg in legs: + d, xc = _find_closest_point_on_leg(lc[leg[0]], lc[leg[1]], point) + if d < dmin: + dmin = d + xcmin = xc + legmin = leg + + return (dmin, xcmin, legmin) class ContourSet(cm.ScalarMappable, ContourLabeler): """ @@ -1262,26 +1327,27 @@ def find_nearest_contour(self, x, y, indices=None, pixel=True): xmin = None ymin = None + point = np.array([x,y]) + for icon in indices: con = self.collections[icon] trans = con.get_transform() paths = con.get_paths() + for segNum, linepath in enumerate(paths): lc = linepath.vertices - # transfer all data points to screen coordinates if desired if pixel: lc = trans.transform(lc) - ds = (lc[:, 0] - x) ** 2 + (lc[:, 1] - y) ** 2 - d = min(ds) + d, xc, leg = _find_closest_point_on_path(lc, point) if d < dmin: dmin = d conmin = icon segmin = segNum - imin = mpl.mlab.find(ds == d)[0] - xmin = lc[imin, 0] - ymin = lc[imin, 1] + imin = leg[1] + xmin = xc[0] + ymin = xc[1] return (conmin, segmin, imin, xmin, ymin, dmin) From d6a70a788f337a5fd10cb7608b090aac58402cc6 Mon Sep 17 00:00:00 2001 From: Brian Mattern Date: Thu, 28 Mar 2013 09:24:01 -0700 Subject: [PATCH 2/8] pep-8 compliance for commit 283f358 --- lib/matplotlib/contour.py | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/lib/matplotlib/contour.py b/lib/matplotlib/contour.py index fdf0bb37edb3..0c02b00b61e2 100644 --- a/lib/matplotlib/contour.py +++ b/lib/matplotlib/contour.py @@ -577,12 +577,12 @@ def add_label_near(self, x, y, inline=True, inline_spacing=5, paths = self.collections[conmin].get_paths() lc = paths[segmin].vertices if transform: - xcmin = transform.inverted().transform([xmin,ymin]) + xcmin = transform.inverted().transform([xmin, ymin]) else: - xcmin = np.array([xmin,ymin]) + xcmin = np.array([xmin, ymin]) if not np.allclose(xcmin, lc[imin]): - lc = np.r_[lc[:imin], np.array(xcmin)[None,:], lc[imin:]] - paths[segmin] = mpath.Path(lc) + lc = np.r_[lc[:imin], np.array(xcmin)[None, :], lc[imin:]] + paths[segmin] = mpath.Path(lc) # Get index of nearest level in subset of levels used for labeling lmin = self.labelIndiceList.index(conmin) @@ -685,6 +685,7 @@ def labels(self, inline, inline_spacing): del paths[:] paths.extend(additions) + def _find_closest_point_on_leg(p1, p2, p0): '''find closest point to p0 on line segment connecting p1 and p2''' @@ -698,8 +699,10 @@ def _find_closest_point_on_leg(p1, p2, p0): # project on to line segment to find closest point proj = np.dot(d01, d21) / np.dot(d21, d21) - if proj < 0: proj = 0 - if proj > 1: proj = 1 + if proj < 0: + proj = 0 + if proj > 1: + proj = 1 pc = p1 + proj * d21 # find squared distance @@ -707,6 +710,7 @@ def _find_closest_point_on_leg(p1, p2, p0): return d, pc + def _find_closest_point_on_path(lc, point): ''' lc: coordinates of vertices @@ -714,21 +718,21 @@ def _find_closest_point_on_path(lc, point): ''' # find index of closest vertex for this segment - ds = np.sum((lc - point[None,:])**2, 1) + ds = np.sum((lc - point[None, :])**2, 1) imin = np.argmin(ds) dmin = 1e10 xcmin = None - legmin = (None,None) + legmin = (None, None) closed = mlab.is_closed_polygon(lc) # build list of legs before and after this vertex legs = [] if imin > 0 or closed: - legs.append(((imin-1)%len(lc),imin)) + legs.append(((imin-1) % len(lc), imin)) if imin < len(lc) - 1 or closed: - legs.append((imin,(imin+1)%len(lc))) + legs.append((imin, (imin+1) % len(lc))) for leg in legs: d, xc = _find_closest_point_on_leg(lc[leg[0]], lc[leg[1]], point) @@ -739,6 +743,7 @@ def _find_closest_point_on_path(lc, point): return (dmin, xcmin, legmin) + class ContourSet(cm.ScalarMappable, ContourLabeler): """ Store a set of contour lines or filled regions. @@ -1327,7 +1332,7 @@ def find_nearest_contour(self, x, y, indices=None, pixel=True): xmin = None ymin = None - point = np.array([x,y]) + point = np.array([x, y]) for icon in indices: con = self.collections[icon] From 2cfb857e4a93a41f603ab8facd5869b11e4a5931 Mon Sep 17 00:00:00 2001 From: Brian Mattern Date: Thu, 28 Mar 2013 09:28:54 -0700 Subject: [PATCH 3/8] pep-8 compliance for rest of contour.py --- lib/matplotlib/contour.py | 84 +++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/lib/matplotlib/contour.py b/lib/matplotlib/contour.py index 0c02b00b61e2..cbb7ee816e1d 100644 --- a/lib/matplotlib/contour.py +++ b/lib/matplotlib/contour.py @@ -633,8 +633,8 @@ def labels(self, inline, inline_spacing): add_label = self.add_label for icon, lev, fsize, cvalue in zip( - self.labelIndiceList, self.labelLevelList, self.labelFontSizeList, - self.labelCValueList): + self.labelIndiceList, self.labelLevelList, + self.labelFontSizeList, self.labelCValueList): con = self.collections[icon] trans = con.get_transform() @@ -902,12 +902,13 @@ def __init__(self, ax, *args, **kwargs): paths = self._make_paths(segs, kinds) # Default zorder taken from Collection zorder = kwargs.get('zorder', 1) - col = mcoll.PathCollection(paths, - antialiaseds=(self.antialiased,), - edgecolors='none', - alpha=self.alpha, - transform=self.get_transform(), - zorder=zorder) + col = mcoll.PathCollection( + paths, + antialiaseds=(self.antialiased,), + edgecolors='none', + alpha=self.alpha, + transform=self.get_transform(), + zorder=zorder) self.ax.add_collection(col) self.collections.append(col) else: @@ -921,13 +922,14 @@ def __init__(self, ax, *args, **kwargs): zip(self.levels, tlinewidths, tlinestyles, self.allsegs): # Default zorder taken from LineCollection zorder = kwargs.get('zorder', 2) - col = mcoll.LineCollection(segs, - antialiaseds=aa, - linewidths=width, - linestyle=[lstyle], - alpha=self.alpha, - transform=self.get_transform(), - zorder=zorder) + col = mcoll.LineCollection( + segs, + antialiaseds=aa, + linewidths=width, + linestyle=[lstyle], + alpha=self.alpha, + transform=self.get_transform(), + zorder=zorder) col.set_label('_nolegend_') self.ax.add_collection(col, False) self.collections.append(col) @@ -972,29 +974,27 @@ def legend_elements(self, variable_name='x', str_format=str): n_levels = len(self.collections) for i, (collection, lower, upper) in enumerate( - zip(self.collections, - lowers, uppers)): - patch = mpatches.Rectangle( - (0, 0), 1, 1, - facecolor=collection.get_facecolor()[0], - hatch=collection.get_hatch(), - alpha=collection.get_alpha(), - ) - artists.append(patch) - - lower = str_format(lower) - upper = str_format(upper) - - if i == 0 and self.extend in ('min', 'both'): - labels.append(r'$%s \leq %s$' % (variable_name, - lower)) - elif i == n_levels - 1 and self.extend in ('max', 'both'): - labels.append(r'$%s > %s$' % (variable_name, - upper)) - else: - labels.append(r'$%s < %s \leq %s$' % (lower, - variable_name, - upper)) + zip(self.collections, lowers, uppers)): + patch = mpatches.Rectangle( + (0, 0), 1, 1, + facecolor=collection.get_facecolor()[0], + hatch=collection.get_hatch(), + alpha=collection.get_alpha()) + artists.append(patch) + + lower = str_format(lower) + upper = str_format(upper) + + if i == 0 and self.extend in ('min', 'both'): + labels.append(r'$%s \leq %s$' % (variable_name, + lower)) + elif i == n_levels - 1 and self.extend in ('max', 'both'): + labels.append(r'$%s > %s$' % (variable_name, + upper)) + else: + labels.append(r'$%s < %s \leq %s$' % (lower, + variable_name, + upper)) else: for collection, level in zip(self.collections, self.levels): @@ -1033,7 +1033,7 @@ def _process_args(self, *args, **kwargs): # Check length of allkinds. if (self.allkinds is not None and - len(self.allkinds) != len(self.allsegs)): + len(self.allkinds) != len(self.allsegs)): raise ValueError('allkinds has different length to allsegs') # Determine x,y bounds and update axes data limits. @@ -1411,7 +1411,7 @@ def _process_args(self, *args, **kwargs): # if the transform is not trans data, and some part of it # contains transData, transform the xs and ys to data coordinates if (t != self.ax.transData and - any(t.contains_branch_seperately(self.ax.transData))): + any(t.contains_branch_seperately(self.ax.transData))): trans_to_data = t - self.ax.transData pts = (np.vstack([x.flat, y.flat]).T) transformed_pts = trans_to_data.transform(pts) @@ -1521,11 +1521,11 @@ def _check_xyz(self, args, kwargs): if x.shape != z.shape: raise TypeError("Shape of x does not match that of z: found " - "{0} instead of {1}.".format(x.shape, z.shape)) + "{0} instead of {1}.".format(x.shape, z.shape)) if y.shape != z.shape: raise TypeError("Shape of y does not match that of z: found " - "{0} instead of {1}.".format(y.shape, z.shape)) + "{0} instead of {1}.".format(y.shape, z.shape)) else: From 4ab3dd908ad83b7c3b0ed497368d6dbeabf032db Mon Sep 17 00:00:00 2001 From: Brian Mattern Date: Thu, 28 Mar 2013 10:06:39 -0700 Subject: [PATCH 4/8] mention contour plot label positioning in whats_new.rst --- doc/users/whats_new.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/users/whats_new.rst b/doc/users/whats_new.rst index 52573d38f554..29a8832464b4 100644 --- a/doc/users/whats_new.rst +++ b/doc/users/whats_new.rst @@ -93,6 +93,16 @@ Andrew Dawson added the ability to add axes titles flush with the left and right sides of the top of the axes using a new keyword argument `loc` to :func:`~matplotlib.pyplot.title`. +Improved manual contour plot label positioning +---------------------------------------------- + +Brian Mattern modified the manual contour plot label positioning code to +interpolate along line segments and find the actual closest point on a +contour to the requested position. Previously, the closest path vertex was +used, which, in the case of straight contours was sometimes quite distant +from the requested location. Much more precise label positioning is now +possible. + .. _whats-new-1-2: new in matplotlib-1.2 From 438c779ae1e9cf9e735f9edd3ce6f9076034442a Mon Sep 17 00:00:00 2001 From: Brian Mattern Date: Thu, 28 Mar 2013 13:09:02 -0700 Subject: [PATCH 5/8] add simple test for contour label positioning --- .../test_contour/contour_manual_labels.pdf | Bin 0 -> 8974 bytes .../test_contour/contour_manual_labels.png | Bin 0 -> 12942 bytes .../test_contour/contour_manual_labels.svg | 844 ++++++++++++++++++ .../contour_manual_labels_pdf.png | Bin 0 -> 2128 bytes .../contour_manual_labels_svg.png | Bin 0 -> 11084 bytes lib/matplotlib/tests/test_contour.py | 14 +- 6 files changed, 857 insertions(+), 1 deletion(-) create mode 100644 lib/matplotlib/tests/baseline_images/test_contour/contour_manual_labels.pdf create mode 100644 lib/matplotlib/tests/baseline_images/test_contour/contour_manual_labels.png create mode 100644 lib/matplotlib/tests/baseline_images/test_contour/contour_manual_labels.svg create mode 100644 lib/matplotlib/tests/baseline_images/test_contour/contour_manual_labels_pdf.png create mode 100644 lib/matplotlib/tests/baseline_images/test_contour/contour_manual_labels_svg.png diff --git a/lib/matplotlib/tests/baseline_images/test_contour/contour_manual_labels.pdf b/lib/matplotlib/tests/baseline_images/test_contour/contour_manual_labels.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e2257693f7c44e0479bd30fd7a7322bbb9e8194d GIT binary patch literal 8974 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 EA26c{bpQYW literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/baseline_images/test_contour/contour_manual_labels.png b/lib/matplotlib/tests/baseline_images/test_contour/contour_manual_labels.png new file mode 100644 index 0000000000000000000000000000000000000000..607b67bb82683eeaa9175fa573d6bcb2757e320b GIT binary patch literal 12942 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_contour/contour_manual_labels_pdf.png b/lib/matplotlib/tests/baseline_images/test_contour/contour_manual_labels_pdf.png new file mode 100644 index 0000000000000000000000000000000000000000..a9860e460e792ab3794ff307857c86bcbac22445 GIT binary patch literal 2128 zcmZuzXH*l&77h?0gce|Nm9ina>@J{)5UM^1O&~9kBF%?L)c^_v2ul+}gg_AKp(T+} z6e&ie6Da`_Q0X9wG%@T;M5?lMMK2=eO14b zpXoVfg7<{-iU|_x!$^A?d|zTkAIeHP(-%My1tfE!j7Weg5dm}qStk5n(`)L!-Ua=` zaG15bAvtP^B(_#?`H=~Mj>4h(=-1bN>bETEEI~{-ica@0SIAn=*=qBWRI&+25BSlOLjNs630VaZBf>nptH>k% z^Zs~^QjE}Uu()*$GWTSO5driJLIR|b(=@1>8bfVz2})oF#3NL6X#mWL2op=#cccvJ z5@DnENY&tqh<6jI{0!oCt2{HoPVv4W$}ff>Xd_U^e=^sS{3Mqw$T0|aGeRLY9uvH z!||E*?qo#Lxlrbj(~vwzn@gNX2#TuJ6JlF4tm3TBF4n}#pjb`sWm}6sPirqNN`oz1 zD#fP3V9SK&yZewg$q09ie;~55hc0}Mv2;WhEX?<+R^e4v$DjA`$JjiKrihTE24}C& zk+HMT#CqWx5Y;?9gEw^-dYR=6t8gMdY9WXHX&j!AzYNtfbwBBURudx6DtnwQ(UPq| zsu`MWKLqj)JHu--PltGp4qav9-*Pt^@&>G#r!f5^sY{xInr~g&N*S1Ob8k(N>4@8# z>gTz%Dr4&H!prwNX)1Cl11hEvlxpWZ_YI~FG+7`=y5(!+KTO>S`-~m0o`YBJ6yyw; zj<|^GG}6nqtCFH|+;>)empktJ?mi(|^ko-2!i3?!LWGVB%X($&NQdeItD;?nu@-{M zTOo;tS562^-EbzQ<|YWWWIMx#x7pcpm~J7HvkU-IoHI15PeqXvM<20m8Hxhm&ol+f z*8YasU7xb3iFgpP$G?ghAOO|lNXxHai*18!?UhsO9d^+J>j+W__;32}*358eW;=2;{^{_B?G#{~^&Wt{2z|85xBcufpg$3UT>1rLu`$A9Z z<3Yv;cE`WmuLnPM)lv±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 VWnAlx)nM`!A}b{?St_pY`#*(9Rigj^ literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/test_contour.py b/lib/matplotlib/tests/test_contour.py index 50681d1232ec..b322f2da5f97 100644 --- a/lib/matplotlib/tests/test_contour.py +++ b/lib/matplotlib/tests/test_contour.py @@ -1,6 +1,6 @@ import numpy as np -from matplotlib.testing.decorators import cleanup +from matplotlib.testing.decorators import cleanup, image_comparison from matplotlib import pyplot as plt @@ -137,3 +137,15 @@ def test_contour_shape_invalid_2(): ax.contour(x, y, z) except TypeError as exc: assert exc.args[0] == 'Input z must be a 2D array.' + + +@image_comparison(baseline_images=['contour_manual_labels']) +def test_contour_manual_labels(): + + x, y = np.meshgrid(np.arange(0, 10), np.arange(0, 10)) + z = np.max(np.dstack([abs(x), abs(y)]), 2) + + plt.figure(figsize=(6, 2)) + cs = plt.contour(x,y,z) + pts = np.array([(1.5, 3.0), (1.5, 4.4), (1.5, 6.0)]) + plt.clabel(cs, manual=pts) From 3cd97ead13614a386664826f42e638d50b4720e3 Mon Sep 17 00:00:00 2001 From: Brian Mattern Date: Thu, 28 Mar 2013 22:53:57 -0700 Subject: [PATCH 6/8] remove uneeded files --- .../test_contour/contour_manual_labels_pdf.png | Bin 2128 -> 0 bytes .../test_contour/contour_manual_labels_svg.png | Bin 11084 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 lib/matplotlib/tests/baseline_images/test_contour/contour_manual_labels_pdf.png delete mode 100644 lib/matplotlib/tests/baseline_images/test_contour/contour_manual_labels_svg.png diff --git a/lib/matplotlib/tests/baseline_images/test_contour/contour_manual_labels_pdf.png b/lib/matplotlib/tests/baseline_images/test_contour/contour_manual_labels_pdf.png deleted file mode 100644 index a9860e460e792ab3794ff307857c86bcbac22445..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2128 zcmZuzXH*l&77h?0gce|Nm9ina>@J{)5UM^1O&~9kBF%?L)c^_v2ul+}gg_AKp(T+} z6e&ie6Da`_Q0X9wG%@T;M5?lMMK2=eO14b zpXoVfg7<{-iU|_x!$^A?d|zTkAIeHP(-%My1tfE!j7Weg5dm}qStk5n(`)L!-Ua=` zaG15bAvtP^B(_#?`H=~Mj>4h(=-1bN>bETEEI~{-ica@0SIAn=*=qBWRI&+25BSlOLjNs630VaZBf>nptH>k% z^Zs~^QjE}Uu()*$GWTSO5driJLIR|b(=@1>8bfVz2})oF#3NL6X#mWL2op=#cccvJ z5@DnENY&tqh<6jI{0!oCt2{HoPVv4W$}ff>Xd_U^e=^sS{3Mqw$T0|aGeRLY9uvH z!||E*?qo#Lxlrbj(~vwzn@gNX2#TuJ6JlF4tm3TBF4n}#pjb`sWm}6sPirqNN`oz1 zD#fP3V9SK&yZewg$q09ie;~55hc0}Mv2;WhEX?<+R^e4v$DjA`$JjiKrihTE24}C& zk+HMT#CqWx5Y;?9gEw^-dYR=6t8gMdY9WXHX&j!AzYNtfbwBBURudx6DtnwQ(UPq| zsu`MWKLqj)JHu--PltGp4qav9-*Pt^@&>G#r!f5^sY{xInr~g&N*S1Ob8k(N>4@8# z>gTz%Dr4&H!prwNX)1Cl11hEvlxpWZ_YI~FG+7`=y5(!+KTO>S`-~m0o`YBJ6yyw; zj<|^GG}6nqtCFH|+;>)empktJ?mi(|^ko-2!i3?!LWGVB%X($&NQdeItD;?nu@-{M zTOo;tS562^-EbzQ<|YWWWIMx#x7pcpm~J7HvkU-IoHI15PeqXvM<20m8Hxhm&ol+f z*8YasU7xb3iFgpP$G?ghAOO|lNXxHai*18!?UhsO9d^+J>j+W__;32}*358eW;=2;{^{_B?G#{~^&Wt{2z|85xBcufpg$3UT>1rLu`$A9Z z<3Yv;cE`WmuLnPM)lv±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 VWnAlx)nM`!A}b{?St_pY`#*(9Rigj^ From 0b72b18d6eeac7cb827222b8812dc462af88742d Mon Sep 17 00:00:00 2001 From: Brian Mattern Date: Sun, 31 Mar 2013 21:54:41 -0700 Subject: [PATCH 7/8] use """ everywhere instead of ''' --- lib/matplotlib/contour.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib/matplotlib/contour.py b/lib/matplotlib/contour.py index cbb7ee816e1d..a939a02ff68d 100644 --- a/lib/matplotlib/contour.py +++ b/lib/matplotlib/contour.py @@ -49,7 +49,7 @@ def get_rotation(self): class ContourLabeler: - '''Mixin to provide labelling capability to ContourSet''' + """Mixin to provide labelling capability to ContourSet""" def clabel(self, *args, **kwargs): """ @@ -620,7 +620,7 @@ def add_label_near(self, x, y, inline=True, inline_spacing=5, paths.append(mpath.Path(n)) def pop_label(self, index=-1): - '''Defaults to removing last label, but any index can be supplied''' + """Defaults to removing last label, but any index can be supplied""" self.labelCValues.pop(index) t = self.labelTexts.pop(index) t.remove() @@ -687,7 +687,7 @@ def labels(self, inline, inline_spacing): def _find_closest_point_on_leg(p1, p2, p0): - '''find closest point to p0 on line segment connecting p1 and p2''' + """find closest point to p0 on line segment connecting p1 and p2""" # handle degenerate case if np.all(p2 == p1): @@ -712,10 +712,10 @@ def _find_closest_point_on_leg(p1, p2, p0): def _find_closest_point_on_path(lc, point): - ''' + """ lc: coordinates of vertices point: coordinates of test point - ''' + """ # find index of closest vertex for this segment ds = np.sum((lc - point[None, :])**2, 1) @@ -1102,7 +1102,7 @@ def changed(self): cm.ScalarMappable.changed(self) def _autolev(self, z, N): - ''' + """ Select contour levels to span the data. We need two more levels for filled contours than for @@ -1111,7 +1111,7 @@ def _autolev(self, z, N): a single contour boundary, say at z = 0, requires only one contour line, but two filled regions, and therefore three levels to provide boundaries for both regions. - ''' + """ if self.locator is None: if self.logscale: self.locator = ticker.LogLocator() @@ -1280,11 +1280,11 @@ def _process_linestyles(self): return tlinestyles def get_alpha(self): - '''returns alpha to be applied to all ContourSet artists''' + """returns alpha to be applied to all ContourSet artists""" return self.alpha def set_alpha(self, alpha): - '''sets alpha for all ContourSet artists''' + """sets alpha for all ContourSet artists""" self.alpha = alpha self.changed() @@ -1479,14 +1479,14 @@ def _contour_args(self, args, kwargs): return (x, y, z) def _check_xyz(self, args, kwargs): - ''' + """ For functions like contour, check that the dimensions of the input arrays match; if x and y are 1D, convert them to 2D using meshgrid. Possible change: I think we should make and use an ArgumentError Exception class (here and elsewhere). - ''' + """ x, y = args[:2] self.ax._process_unit_info(xdata=x, ydata=y, kwargs=kwargs) x = self.ax.convert_xunits(x) @@ -1534,7 +1534,7 @@ def _check_xyz(self, args, kwargs): return x, y, z def _initialize_x_y(self, z): - ''' + """ Return X, Y arrays such that contour(Z) will match imshow(Z) if origin is not None. The center of pixel Z[i,j] depends on origin: @@ -1545,7 +1545,7 @@ def _initialize_x_y(self, z): as in imshow. If origin is None and extent is not None, then extent will give the minimum and maximum values of x and y. - ''' + """ if z.ndim != 2: raise TypeError("Input must be a 2D array.") else: From b2c0352f509fb2ea31dd420d78dc1782b114340e Mon Sep 17 00:00:00 2001 From: Brian Mattern Date: Sun, 31 Mar 2013 21:56:39 -0700 Subject: [PATCH 8/8] use np.inf instead of arbitrary 1e10 --- lib/matplotlib/contour.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/matplotlib/contour.py b/lib/matplotlib/contour.py index a939a02ff68d..26b93d0cfa4a 100644 --- a/lib/matplotlib/contour.py +++ b/lib/matplotlib/contour.py @@ -721,7 +721,7 @@ def _find_closest_point_on_path(lc, point): ds = np.sum((lc - point[None, :])**2, 1) imin = np.argmin(ds) - dmin = 1e10 + dmin = np.inf xcmin = None legmin = (None, None) @@ -1326,7 +1326,7 @@ def find_nearest_contour(self, x, y, indices=None, pixel=True): if indices is None: indices = range(len(self.levels)) - dmin = 1e10 + dmin = np.inf conmin = None segmin = None xmin = None