10000 Improve Gradient bar example (#14057) · matplotlib/matplotlib@1f22f41 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1f22f41

Browse files
authored
Improve Gradient bar example (#14057)
Improve Gradient bar example
2 parents 088ed59 + eca1796 commit 1f22f41

File tree

1 file changed

+58
-12
lines changed

1 file changed

+58
-12
lines changed
Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,21 @@
11
"""
2-
============
3-
Gradient Bar
4-
============
2+
========================
3+
Bar chart with gradients
4+
========================
5+
6+
Matplotlib does not natively support gradients. However, we can emulate a
7+
gradient-filled rectangle by an `.AxesImage` of the right size and coloring.
8+
9+
In particular, we use a colormap to generate the actual colors. It is then
10+
sufficient to define the underlying values on the corners of the image and
11+
let bicubic interpolation fill out the area. We define the gradient direction
12+
by a unit vector *v*. The values at the corners are then obtained by the
13+
lengths of the projections of the corner vectors on *v*.
14+
15+
A similar approach can be used to create a gradient background for an axes.
16+
In that case, it is helpful to uses Axes coordinates
17+
(`extent=(0, 1, 0, 1), transform=ax.transAxes`) to be independent of the data
18+
coordinates.
519
620
"""
721
import matplotlib.pyplot as plt
@@ -10,12 +24,44 @@
1024
np.random.seed(19680801)
1125

1226

13-
def gbar(ax, x, y, width=0.5, bottom=0):
14-
X = [[.6, .6], [.7, .7]]
27+
def gradient_image(ax, extent, direction=0.3, cmap_range=(0, 1), **kwargs):
28+
"""
29+
Draw a gradient image based on a colormap.
30+
31+
Parameters
32+
----------
33+
ax : Axes
34+
The axes to draw on.
35+
extent
36+
The extent of the image as (xmin, xmax, ymin, ymax).
37+
By default, this is in Axes coordinates but may be
38+
changed using the *transform* kwarg.
39+
direction : float
40+
The direction of the gradient. This is a number in
41+
range 0 (=vertical) to 1 (=horizontal).
42+
cmap_range : float, float
43+
The fraction (cmin, cmax) of the colormap that should be
44+
used for the gradient, where the complete colormap is (0, 1).
45+
**kwargs
46+
Other parameters are passed on to `.Axes.imshow()`.
47+
In particular useful is *cmap*.
48+
"""
49+
phi = direction * np.pi / 2
50+
v = np.array([np.cos(phi), np.sin(phi)])
51+
X = np.array([[v @ [1, 0], v @ [1, 1]],
52+
[v @ [0, 0], v @ [0, 1]]])
53+
a, b = cmap_range
54+
X = a + (b - a) / X.max() * X
55+
im = ax.imshow(X, extent=extent, interpolation='bicubic',
56+
vmin=0, vmax=1, **kwargs)
57+
return im
58+
59+
60+
def gradient_bar(ax, x, y, width=0.5, bottom=0):
1561
for left, top in zip(x, y):
1662
right = left + width
17-
ax.imshow(X, interpolation='bicubic', cmap=plt.cm.Blues,
18-
extent=(left, right, bottom, top), alpha=1)
63+
gradient_image(ax, extent=(left, right, bottom, top),
64+
cmap=plt.cm.Blues_r, cmap_range=(0, 0.8))
1965

2066

2167
xmin, xmax = xlim = 0, 10
@@ -24,13 +70,13 @@ def gbar(ax, x, y, width=0.5, bottom=0):
2470
fig, ax = plt.subplots()
2571
ax.set(xlim=xlim, ylim=ylim, autoscale_on=False)
2672

27-
X = [[.6, .6], [.7, .7]]
28-
ax.imshow(X, interpolation='bicubic', cmap=plt.cm.copper,
29-
extent=(xmin, xmax, ymin, ymax), alpha=1)
73+
# background image
74+
gradient_image(ax, direction=0, extent=(0, 1, 0, 1), transform=ax.transAxes,
75+
cmap=plt.cm.Oranges, cmap_range=(0.1, 0.6))
3076

3177
N = 10
32-
x = np.arange(N) + 0.25
78+
x = np.arange(N) + 0.15
3379
y = np.random.rand(N)
34-
gbar(ax, x, y, width=0.7)
80+
gradient_bar(ax, x, y, width=0.7)
3581
ax.set_aspect('auto')
3682
plt.show()

0 commit comments

Comments
 (0)
0