python - Is it possible to get color gradients under curve in matplotlib? -
i happened see beautiful graphs on page shown below:
is possible such color gradients in matplotlib?
there have been handful of previous answers similar questions (e.g. https://stackoverflow.com/a/22081678/325565), recommend sub-optimal approach.
most of previous answers recommend plotting white polygon on pcolormesh
fill. less ideal 2 reasons:
- the background of axes can't transparent, there's filled polygon overlying it
pcolormesh
slow draw , isn't smoothly interpolated.
it's touch more work, there's method draws faster , gives better visual result: set clip path of image plotted imshow
.
as example:
import numpy np import matplotlib.pyplot plt import matplotlib.colors mcolors matplotlib.patches import polygon np.random.seed(1977) def main(): _ in range(5): gradient_fill(*generate_data(100)) plt.show() def generate_data(num): x = np.linspace(0, 100, num) y = np.random.normal(0, 1, num).cumsum() return x, y def gradient_fill(x, y, fill_color=none, ax=none, **kwargs): """ plot line linear alpha gradient filled beneath it. parameters ---------- x, y : array-like data values of line. fill_color : matplotlib color specifier (string, tuple) or none color fill. if none, color of line used. ax : matplotlib axes instance axes plot on. if none, current pyplot axes used. additional arguments passed on matplotlib's ``plot`` function. returns ------- line : line2d instance line plotted. im : axesimage instance transparent gradient clipped area beneath curve. """ if ax none: ax = plt.gca() line, = ax.plot(x, y, **kwargs) if fill_color none: fill_color = line.get_color() zorder = line.get_zorder() alpha = line.get_alpha() alpha = 1.0 if alpha none else alpha z = np.empty((100, 1, 4), dtype=float) rgb = mcolors.colorconverter.to_rgb(fill_color) z[:,:,:3] = rgb z[:,:,-1] = np.linspace(0, alpha, 100)[:,none] xmin, xmax, ymin, ymax = x.min(), x.max(), y.min(), y.max() im = ax.imshow(z, aspect='auto', extent=[xmin, xmax, ymin, ymax], origin='lower', zorder=zorder) xy = np.column_stack([x, y]) xy = np.vstack([[xmin, ymin], xy, [xmax, ymin], [xmin, ymin]]) clip_path = polygon(xy, facecolor='none', edgecolor='none', closed=true) ax.add_patch(clip_path) im.set_clip_path(clip_path) ax.autoscale(true) return line, im main()
Comments
Post a Comment