diff --git a/examples/pylab_examples/quiver_demo.py b/examples/pylab_examples/quiver_demo.py index 72bb275808be..067d6029e82d 100644 --- a/examples/pylab_examples/quiver_demo.py +++ b/examples/pylab_examples/quiver_demo.py @@ -1,12 +1,12 @@ ''' -Demonstration of quiver and quiverkey functions. This is using the -new version coming from the code in quiver.py. +======================================================== +Demonstration of advanced quiver and quiverkey functions +======================================================== Known problem: the plot autoscaling does not take into account the arrows, so those on the boundaries are often out of the picture. This is *not* an easy problem to solve in a perfectly general way. The workaround is to manually expand the axes. - ''' import matplotlib.pyplot as plt import numpy as np @@ -16,81 +16,27 @@ U = np.cos(X) V = np.sin(Y) -# 1 -plt.figure() -Q = plt.quiver(U, V) -qk = plt.quiverkey(Q, 0.5, 0.98, 2, r'$2 \frac{m}{s}$', labelpos='W', - fontproperties={'weight': 'bold'}) -l, r, b, t = plt.axis() -dx, dy = r - l, t - b -plt.axis([l - 0.05*dx, r + 0.05*dx, b - 0.05*dy, t + 0.05*dy]) - -plt.title('Minimal arguments, no kwargs') - -# 2 plt.figure() +plt.title('Arrows scale with plot width, not view') Q = plt.quiver(X, Y, U, V, units='width') -qk = plt.quiverkey(Q, 0.9, 0.95, 2, r'$2 \frac{m}{s}$', - labelpos='E', - coordinates='figure', - fontproperties={'weight': 'bold'}) -plt.axis([-1, 7, -1, 7]) -plt.title('scales with plot width, not view') +qk = plt.quiverkey(Q, 0.9, 0.9, 2, r'$2 \frac{m}{s}$', labelpos='E', + coordinates='figure') -# 3 plt.figure() -Q = plt.quiver(X[::3, ::3], Y[::3, ::3], U[::3, ::3], V[::3, ::3], - pivot='mid', color='r', units='inches') -qk = plt.quiverkey(Q, 0.5, 0.03, 1, r'$1 \frac{m}{s}$', - fontproperties={'weight': 'bold'}) -plt.plot(X[::3, ::3], Y[::3, ::3], 'k.') -plt.axis([-1, 7, -1, 7]) plt.title("pivot='mid'; every third arrow; units='inches'") +Q = plt.quiver(X[::3, ::3], Y[::3, ::3], U[::3, ::3], V[::3, ::3], + pivot='mid', units='inches') +qk = plt.quiverkey(Q, 0.9, 0.9, 1, r'$1 \frac{m}{s}$', labelpos='E', + coordinates='figure') +plt.scatter(X[::3, ::3], Y[::3, ::3], color='r', s=5) -# 4 plt.figure() +plt.title("pivot='tip'; scales with x view") M = np.hypot(U, V) -Q = plt.quiver(X, Y, U, V, M, - units='x', - pivot='tip', - width=0.022, +Q = plt.quiver(X, Y, U, V, M, units='x', pivot='tip', width=0.022, scale=1 / 0.15) -qk = plt.quiverkey(Q, 0.9, 1.05, 1, r'$1 \frac{m}{s}$', - labelpos='E', - fontproperties={'weight': 'bold'}) -plt.plot(X, Y, 'k.', markersize=2) -plt.axis([-1, 7, -1, 7]) -plt.title("scales with x view; pivot='tip'") - -# 5 -plt.figure() -Q = plt.quiver(X[::3, ::3], Y[::3, ::3], U[::3, ::3], V[::3, ::3], - color='r', units='x', - linewidths=(0.5,), edgecolors=('k'), headaxislength=5) -qk = plt.quiverkey(Q, 0.5, 0.03, 1, r'$1 \frac{m}{s}$', - fontproperties={'weight': 'bold'}) -plt.axis([-1, 7, -1, 7]) -plt.title("triangular head; scale with x view; black edges") - -# 6 -plt.figure() -M = np.zeros(U.shape, dtype='bool') -XMaskStart = U.shape[0]//3 -YMaskStart = U.shape[1]//3 -XMaskStop = 2*U.shape[0]//3 -YMaskStop = 2*U.shape[1]//3 - -M[XMaskStart:XMaskStop, - YMaskStart:YMaskStop] = True -U = ma.masked_array(U, mask=M) -V = ma.masked_array(V, mask=M) -Q = plt.quiver(U, V) -qk = plt.quiverkey(Q, 0.5, 0.98, 2, r'$2 \frac{m}{s}$', labelpos='W', - fontproperties={'weight': 'bold'}) -l, r, b, t = plt.axis() -dx, dy = r - l, t - b -plt.axis([l - 0.05 * dx, r + 0.05 * dx, b - 0.05 * dy, t + 0.05 * dy]) -plt.title('Minimal arguments, no kwargs - masked values') - +qk = plt.quiverkey(Q, 0.9, 0.9, 1, r'$1 \frac{m}{s}$', labelpos='E', + coordinates='figure') +plt.scatter(X, Y, color='k', s=5) plt.show() diff --git a/examples/pylab_examples/quiver_simple_demo.py b/examples/pylab_examples/quiver_simple_demo.py new file mode 100644 index 000000000000..417b9c2b03ad --- /dev/null +++ b/examples/pylab_examples/quiver_simple_demo.py @@ -0,0 +1,18 @@ +''' +================================================== +A simple example of a quiver plot with a quiverkey +================================================== +''' +import matplotlib.pyplot as plt +import numpy as np + +X = np.arange(-10, 10, 1) +Y = np.arange(-10, 10, 1) +U, V = np.meshgrid(X, Y) + +fig, ax = plt.subplots() +q = ax.quiver(X, Y, U, V) +ax.quiverkey(q, X=0.3, Y=1.1, U=10, + label='Quiver key, length = 10', labelpos='E') + +plt.show() diff --git a/lib/matplotlib/quiver.py b/lib/matplotlib/quiver.py index 83a3a26019c8..d889926e6c7c 100644 --- a/lib/matplotlib/quiver.py +++ b/lib/matplotlib/quiver.py @@ -38,45 +38,57 @@ _quiver_doc = """ Plot a 2-D field of arrows. -call signatures:: +Call signatures:: quiver(U, V, **kw) quiver(U, V, C, **kw) quiver(X, Y, U, V, **kw) quiver(X, Y, U, V, C, **kw) -Arguments: - - *X*, *Y*: - The x and y coordinates of the arrow locations (default is tail of - arrow; see *pivot* kwarg) - - *U*, *V*: - Give the x and y components of the arrow vectors +*U* and *V* are the arrow data, *X* and *Y* set the locaiton of the +arrows, and *C* sets the color of the arrows. These arguments may be 1-D or +2-D arrays or sequences. - *C*: - An optional array used to map colors to the arrows - -All arguments may be 1-D or 2-D arrays or sequences. If *X* and *Y* -are absent, they will be generated as a uniform grid. If *U* and *V* -are 2-D arrays but *X* and *Y* are 1-D, and if ``len(X)`` and ``len(Y)`` -match the column and row dimensions of *U*, then *X* and *Y* will be +If *X* and *Y* are absent, they will be generated as a uniform grid. +If *U* and *V* are 2-D arrays and *X* and *Y* are 1-D, and if ``len(X)`` and +``len(Y)`` match the column and row dimensions of *U*, then *X* and *Y* will be expanded with :func:`numpy.meshgrid`. -*U*, *V*, *C* may be masked arrays, but masked *X*, *Y* are not -supported at present. +The default settings auto-scales the length of the arrows to a reasonable size. +To change this behavior see the *scale* and *scale_units* kwargs. -Keyword arguments: +The defaults give a slightly swept-back arrow; to make the head a +triangle, make *headaxislength* the same as *headlength*. To make the +arrow more pointed, reduce *headwidth* or increase *headlength* and +*headaxislength*. To make the head smaller relative to the shaft, +scale down all the head parameters. You will probably do best to leave +minshaft alone. + +*linewidths* and *edgecolors* can be used to customize the arrow +outlines. - *units*: [ 'width' | 'height' | 'dots' | 'inches' | 'x' | 'y' | 'xy' ] - Arrow units; the arrow dimensions *except for length* are in - multiples of this unit. +Parameters +---------- +X : 1D or 2D array, sequence, optional + The x coordinates of the arrow locations +Y : 1D or 2D array, sequence, optional + The y coordinates of the arrow locations +U : 1D or 2D array or masked array, sequence + The x components of the arrow vectors +V : 1D or 2D array or masked array, sequence + The y components of the arrow vectors +C : 1D or 2D array, sequence, optional + The arrow colors +units : [ 'width' | 'height' | 'dots' | 'inches' | 'x' | 'y' | 'xy' ] + The arrow dimensions (except for *length*) are measured in multiples of + this unit. - * 'width' or 'height': the width or height of the axes + 'width' or 'height': the width or height of the axis - * 'dots' or 'inches': pixels or inches, based on the figure dpi + 'dots' or 'inches': pixels or inches, based on the figure dpi - * 'x', 'y', or 'xy': *X*, *Y*, or sqrt(X^2+Y^2) data units + 'x', 'y', or 'xy': respectively *X*, *Y*, or :math:`\sqrt{X^2 + Y^2}` + in data units The arrows scale differently depending on the units. For 'x' or 'y', the arrows get larger as one zooms in; for other @@ -84,82 +96,82 @@ 'width or 'height', the arrow size increases with the width and height of the axes, respectively, when the window is resized; for 'dots' or 'inches', resizing does not change the arrows. +angles : [ 'uv' | 'xy' ], array, optional + Method for determining the angle of the arrows. Default is 'uv'. - - *angles*: [ 'uv' | 'xy' | array ] - With the default 'uv', the arrow axis aspect ratio is 1, so that + 'uv': the arrow axis aspect ratio is 1 so that if *U*==*V* the orientation of the arrow on the plot is 45 degrees - CCW from the horizontal axis (positive to the right). - With 'xy', the arrow points from (x,y) to (x+u, y+v). + counter-clockwise from the horizontal axis (positive to the right). + + 'xy': arrows point from (x,y) to (x+u, y+v). Use this for plotting a gradient field, for example. + Alternatively, arbitrary angles may be specified as an array - of values in degrees, CCW from the horizontal axis. + of values in degrees, counter-clockwise from the horizontal axis. + Note: inverting a data axis will correspondingly invert the - arrows *only* with `angles='xy'`. + arrows only with ``angles='xy'``. +scale : None, float, optional + Number of data units per arrow length unit, e.g., m/s per plot width; a + smaller scale parameter makes the arrow longer. Default is *None*. - *scale*: [ *None* | float ] - Data units per arrow length unit, e.g., m/s per plot width; a smaller - scale parameter makes the arrow longer. If *None*, a simple - autoscaling algorithm is used, based on the average vector length - and the number of vectors. The arrow length unit is given by + If *None*, a simple autoscaling algorithm is used, based on the average + vector length and the number of vectors. The arrow length unit is given by the *scale_units* parameter +scale_units : [ 'width' | 'height' | 'dots' | 'inches' | 'x' | 'y' | 'xy' ], \ +None, optional + If the *scale* kwarg is *None*, the arrow length unit. Default is *None*. - *scale_units*: *None*, or any of the *units* options. - For example, if *scale_units* is 'inches', *scale* is 2.0, and + e.g. *scale_units* is 'inches', *scale* is 2.0, and ``(u,v) = (1,0)``, then the vector will be 0.5 inches long. - If *scale_units* is 'width', then the vector will be half the width - of the axes. + + If *scale_units* is 'width'/'height', then the vector will be half the + width/height of the axes. If *scale_units* is 'x' then the vector will be 0.5 x-axis - units. To plot vectors in the x-y plane, with u and v having + units. To plot vectors in the x-y plane, with u and v having the same units as x and y, use - "angles='xy', scale_units='xy', scale=1". - - *width*: + ``angles='xy', scale_units='xy', scale=1``. +width : scalar, optional Shaft width in arrow units; default depends on choice of units, above, and number of vectors; a typical starting value is about 0.005 times the width of the plot. - - *headwidth*: scalar +headwidth : scalar, optional Head width as multiple of shaft width, default is 3 - - *headlength*: scalar +headlength : scalar, optional Head length as multiple of shaft width, default is 5 - - *headaxislength*: scalar +headaxislength : scalar, optional Head length at shaft intersection, default is 4.5 - - *minshaft*: scalar +minshaft : scalar, optional Length below which arrow scales, in units of head length. Do not set this to less than 1, or small arrows will look terrible! Default is 1 - - *minlength*: scalar +minlength : scalar, optional Minimum length as a multiple of shaft width; if an arrow length is less than this, plot a dot (hexagon) of this diameter instead. Default is 1. - - *pivot*: [ 'tail' | 'mid' | 'middle' | 'tip' ] +pivot : [ 'tail' | 'mid' | 'middle' | 'tip' ], optional The part of the arrow that is at the grid point; the arrow rotates about this point, hence the name *pivot*. - - *color*: [ color | color sequence ] +color : [ color | color sequence ], optional This is a synonym for the :class:`~matplotlib.collections.PolyCollection` facecolor kwarg. If *C* has been set, *color* has no effect. -The defaults give a slightly swept-back arrow; to make the head a -triangle, make *headaxislength* the same as *headlength*. To make the -arrow more pointed, reduce *headwidth* or increase *headlength* and -*headaxislength*. To make the head smaller relative to the shaft, -scale down all the head parameters. You will probably do best to leave -minshaft alone. - -linewidths and edgecolors can be used to customize the arrow -outlines. Additional :class:`~matplotlib.collections.PolyCollection` +Notes +----- +Additional :class:`~matplotlib.collections.PolyCollection` keyword arguments: %(PolyCollection)s + +Examples +-------- +.. plot:: mpl_examples/pylab_examples/quiver_simple_demo.py + +See Also +-------- +quiverkey : Add a key to a quiver plot """ % docstring.interpd.params _quiverkey_doc = """