I am using quiver from matplotlib to plot a vectorial field. I would like to change the size of the thickness of each arrow depending on the number of data which produced a specific arrow of the vector field. Therefore what I am looking for is not a general scale transformation of the arrow size, but the way to customize the thickness of the arrow in quiver one-by-one. Is it possible? Can you help me?
2 Answers
The linewidths
parameter to plt.quiver
controls the thickness of the arrows. If you pass it a 1-dimensional array of values, each arrow gets a different thickness.
For example,
widths = np.linspace(0, 2, X.size)
plt.quiver(X, Y, cos(deg), sin(deg), linewidths=widths)
creates linewidths growing from 0 to 2.
import matplotlib.pyplot as plt
import numpy as np
sin = np.sin
cos = np.cos
# http://stackoverflow.com/questions/6370742/#6372413
xmax = 4.0
xmin = -xmax
D = 20
ymax = 4.0
ymin = -ymax
x = np.linspace(xmin, xmax, D)
y = np.linspace(ymin, ymax, D)
X, Y = np.meshgrid(x, y)
# plots the vector field for Y'=Y**3-3*Y-X
deg = np.arctan(Y ** 3 - 3 * Y - X)
widths = np.linspace(0, 2, X.size)
plt.quiver(X, Y, cos(deg), sin(deg), linewidths=widths)
plt.show()
yields

- 842,883
- 184
- 1,785
- 1,677
-
3This breaks down if you we specify face colors that aren't your line color. Use the `width` keyword instead. – kilojoules Sep 02 '17 at 19:02
-
1Also see: ["Linewidth(s) keywords not working with quiver"](https://github.com/matplotlib/matplotlib/issues/8630) -- github.com/matplotlib/matplotlib – nekketsuuu May 29 '18 at 16:28
@unutbu's solution is not useful after matplotlib 2.0.0 (see this issue and this pull request). As of matplotlib 2.1.2, there seems to be no parameter of plt.quiver
which officially supports one-by-one configuration of arrow widths. But some workarounds are remained.
Method 1
Just use Python's loop and the width
parameter. This will be slow for large data.
import matplotlib.pyplot as plt
import numpy as np
# original code by user423805
# https://stackoverflow.com/a/6372413/5989200
xmax = 4.0
xmin = -xmax
D = 20
ymax = 4.0
ymin = -ymax
for y in np.linspace(ymin, ymax, D):
for x in np.linspace(xmin, xmax, D):
deg = np.arctan(y ** 3 - 3 * y - x)
w = 0.005 * (y - ymin) / (ymax - ymin) # just example...
plt.quiver(x, y, np.cos(deg), np.sin(deg), width=w)
plt.show()
Method 2
This is only a workaround, but linewidths
can be used if we set edgecolors
.
import matplotlib.pyplot as plt
import numpy as np
# original code by user423805
# https://stackoverflow.com/a/6372413/5989200
xmax = 4.0
xmin = -xmax
D = 20
ymax = 4.0
ymin = -ymax
x = np.linspace(xmin, xmax, D)
y = np.linspace(ymin, ymax, D)
X, Y = np.meshgrid(x, y)
deg = np.arctan(Y ** 3 - 3 * Y - X)
widths = np.linspace(0, 2, X.size)
plt.quiver(X, Y, np.cos(deg), np.sin(deg), linewidths=widths, edgecolors='k')
plt.show()
Note that efiring, one of maintainers of matplotlib, said:
So please use the
width
kwarg together withunits
;linewidths
is only for controlling the outline thickness, when an outline of a different color is explicitly requested.

- 1,641
- 1
- 21
- 26