From af170517defe0f4dd7207bee70b82105eb4c0c4a Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sun, 28 Dec 2014 17:20:07 -0500 Subject: [PATCH 1/2] API : tighten validation on pivot in Quiver only accept {'mid', 'middle', 'tip', 'tail'} instead of being super permissive. Closes #3951 --- doc/api/api_changes/2014-12-28_quiver.rst | 12 ++++++++++++ lib/matplotlib/quiver.py | 21 +++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 doc/api/api_changes/2014-12-28_quiver.rst diff --git a/doc/api/api_changes/2014-12-28_quiver.rst b/doc/api/api_changes/2014-12-28_quiver.rst new file mode 100644 index 000000000000..98fc5aed97f5 --- /dev/null +++ b/doc/api/api_changes/2014-12-28_quiver.rst @@ -0,0 +1,12 @@ +Tighted input validation on 'pivot' kwarg to quiver +``````````````````````````````````````````````````` + +Tightened validation so that only {'tip', 'tail', 'mid', and 'middle'} +(but any capitalization) are valid values for the 'pivot' kwarg in +the `Quiver.__init__` (and hence `Axes.quiver` and +`plt.quiver` which both fully delegate to `Quiver`). Previously any +input matching 'mid.*' would be interpreted as 'middle', 'tip.*' as +'tip' and any string not matching one of those patterns as 'tail'. + +The value of `Quiver.pivot` is normalized to be in the set {'tip', +'tail', 'middle'} in `Quiver.__init__`. diff --git a/lib/matplotlib/quiver.py b/lib/matplotlib/quiver.py index 3a7bdaf8f747..76e4a0232881 100644 --- a/lib/matplotlib/quiver.py +++ b/lib/matplotlib/quiver.py @@ -136,7 +136,7 @@ is less than this, plot a dot (hexagon) of this diameter instead. Default is 1. - *pivot*: [ 'tail' | 'middle' | 'tip' ] + *pivot*: [ 'tail' | 'mid' | 'middle' | 'tip' ] The part of the arrow that is at the grid point; the arrow rotates about this point, hence the name *pivot*. @@ -405,6 +405,8 @@ class Quiver(mcollections.PolyCollection): in the draw() method. """ + _PIVOT_VALS = ('tail', 'mid', 'middle', 'tip') + @docstring.Substitution(_quiver_doc) def __init__(self, ax, *args, **kw): """ @@ -430,7 +432,18 @@ def __init__(self, ax, *args, **kw): self.angles = kw.pop('angles', 'uv') self.width = kw.pop('width', None) self.color = kw.pop('color', 'k') - self.pivot = kw.pop('pivot', 'tail') + + pivot = kw.pop('pivot', 'tail').lower() + # validate pivot + if pivot not in self._PIVOT_VALS: + raise ValueError( + 'pivot must be one of {keys}, you passed {inp}'.format( + keys=self._PIVOT_VALS, inp=pivot)) + # normalize to 'middle' + if pivot == 'mid': + pivot = 'middle' + self.pivot = pivot + self.transform = kw.pop('transform', ax.transData) kw.setdefault('facecolors', self.color) kw.setdefault('linewidths', (0,)) @@ -681,9 +694,9 @@ def _h_arrows(self, length): # Now select X0, Y0 if short, otherwise X, Y cbook._putmask(X, short, X0) cbook._putmask(Y, short, Y0) - if self.pivot[:3] == 'mid': + if self.pivot == 'middle': X -= 0.5 * X[:, 3, np.newaxis] - elif self.pivot[:3] == 'tip': + elif self.pivot == 'tip': X = X - X[:, 3, np.newaxis] # numpy bug? using -= does not # work here unless we multiply # by a float first, as with 'mid'. From e6419cfa1615cab4f78d5f66742e805a1919adf1 Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Sun, 28 Dec 2014 22:16:07 -0500 Subject: [PATCH 2/2] PEP8 : comment-related pep8 Fixes 'violations' we don't test for, all white space in comments. --- lib/matplotlib/quiver.py | 57 +++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/lib/matplotlib/quiver.py b/lib/matplotlib/quiver.py index 76e4a0232881..6d33e55baf54 100644 --- a/lib/matplotlib/quiver.py +++ b/lib/matplotlib/quiver.py @@ -247,8 +247,9 @@ def on_dpi_change(fig): if self_weakref is not None: self_weakref.labelsep = (self_weakref._labelsep_inches*fig.dpi) self_weakref._initialized = False # simple brute force update - # works because _init is called - # at the start of draw. + # works because _init is + # called at the start of + # draw. self._cid = Q.ax.figure.callbacks.connect('dpi_changed', on_dpi_change) @@ -258,7 +259,7 @@ def on_dpi_change(fig): self.fontproperties = kw.pop('fontproperties', dict()) self.kw = kw _fp = self.fontproperties - #boxprops = dict(facecolor='red') + # boxprops = dict(facecolor='red') self.text = mtext.Text( text=label, # bbox=boxprops, horizontalalignment=self.halign[self.labelpos], @@ -465,10 +466,11 @@ def on_dpi_change(fig): self_weakref = weak_self() if self_weakref is not None: self_weakref._new_UV = True # vertices depend on width, span - # which in turn depend on dpi + # which in turn depend on dpi self_weakref._initialized = False # simple brute force update - # works because _init is called - # at the start of draw. + # works because _init is + # called at the start of + # draw. self._cid = self.ax.figure.callbacks.connect('dpi_changed', on_dpi_change) @@ -667,7 +669,7 @@ def _h_arrows(self, length): length = length.reshape(N, 1) # This number is chosen based on when pixel values overflow in Agg # causing rendering errors - #length = np.minimum(length, 2 ** 16) + # length = np.minimum(length, 2 ** 16) np.clip(length, 0, 2 ** 16, out=length) # x, y: normal horizontal arrow x = np.array([0, -self.headaxislength, @@ -870,9 +872,9 @@ class Barbs(mcollections.PolyCollection): From there :meth:`_make_barbs` is used to find the vertices of the polygon to represent the barb based on this information. ''' - #This may be an abuse of polygons here to render what is essentially maybe - #1 triangle and a series of lines. It works fine as far as I can tell - #however. + # This may be an abuse of polygons here to render what is essentially maybe + # 1 triangle and a series of lines. It works fine as far as I can tell + # however. @docstring.interpd def __init__(self, ax, *args, **kw): """ @@ -892,10 +894,11 @@ def __init__(self, ax, *args, **kw): self.flip = kw.pop('flip_barb', False) transform = kw.pop('transform', ax.transData) - #Flagcolor and and barbcolor provide convenience parameters for setting - #the facecolor and edgecolor, respectively, of the barb polygon. We - #also work here to make the flag the same color as the rest of the barb - #by default + # Flagcolor and and barbcolor provide convenience parameters for + # setting the facecolor and edgecolor, respectively, of the barb + # polygon. We also work here to make the flag the same color as the + # rest of the barb by default + if None in (barbcolor, flagcolor): kw['edgecolors'] = 'face' if flagcolor: @@ -903,19 +906,19 @@ def __init__(self, ax, *args, **kw): elif barbcolor: kw['facecolors'] = barbcolor else: - #Set to facecolor passed in or default to black + # Set to facecolor passed in or default to black kw.setdefault('facecolors', 'k') else: kw['edgecolors'] = barbcolor kw['facecolors'] = flagcolor - #Parse out the data arrays from the various configurations supported + # Parse out the data arrays from the various configurations supported x, y, u, v, c = _parse_args(*args) self.x = x self.y = y xy = np.hstack((x[:, np.newaxis], y[:, np.newaxis])) - #Make a collection + # Make a collection barb_size = self._length ** 2 / 4 # Empirically determined mcollections.PolyCollection.__init__(self, [], (barb_size,), offsets=xy, @@ -940,8 +943,8 @@ def _find_tails(self, mag, rounding=True, half=5, full=10, flag=50): a barb is empty (too low to plot any barbs/flags. ''' - #If rounding, round to the nearest multiple of half, the smallest - #increment + # If rounding, round to the nearest multiple of half, the smallest + # increment if rounding: mag = half * (mag / half + 0.5).astype(np.int) @@ -1002,17 +1005,17 @@ def _make_barbs(self, u, v, nflags, nbarbs, half_barb, empty_flag, length, properly align with the vector direction. ''' - #These control the spacing and size of barb elements relative to the - #length of the shaft + # These control the spacing and size of barb elements relative to the + # length of the shaft spacing = length * sizes.get('spacing', 0.125) full_height = length * sizes.get('height', 0.4) full_width = length * sizes.get('width', 0.25) empty_rad = length * sizes.get('emptybarb', 0.15) - #Controls y point where to pivot the barb. + # Controls y point where to pivot the barb. pivot_points = dict(tip=0.0, middle=-length / 2.) - #Check for flip + # Check for flip if flip: full_height = -full_height @@ -1039,11 +1042,11 @@ def _make_barbs(self, u, v, nflags, nbarbs, half_barb, empty_flag, length, barb_list = [] for index, angle in np.ndenumerate(angles): - #If the vector magnitude is too weak to draw anything, plot an - #empty circle instead + # If the vector magnitude is too weak to draw anything, plot an + # empty circle instead if empty_flag[index]: - #We can skip the transform since the circle has no preferred - #orientation + # We can skip the transform since the circle has no preferred + # orientation barb_list.append(empty_barb) continue pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy