线条与y = 0之间的渐变颜色的python区域图表

时间:2015-06-16 03:38:10

标签: python charts

我想使用python绘制像this这样的图表。我发现这个Is it possible to get color gradients under curve in matplotlb?,但填充了y = ymin和y之间的区域。我需要的是,如果y> 0,则在y = 0和y之间填充;如果y <0,则填充y和y = 0。

1 个答案:

答案 0 :(得分:0)

更改np.vstack参数。

xy = np.vstack([[xmin, ymin], xy, [xmax, ymin], [xmin, ymin]])

xy = np.vstack([[xmin, 0], xy, [xmax, 0], [xmin, 0]])

完整代码:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
from matplotlib.patches import Polygon
np.random.seed(1977)

def main():
    gradient_fill(np.array([1,2,3,4]),np.array([2,-1,-2,1]))
    plt.show()    

def gradient_fill(x, y, fill_color=None, ax=None, **kwargs):
    """
    Plot a line with a linear alpha gradient filled beneath it.

    Parameters
    ----------
    x, y : array-like
        The data values of the line.
    fill_color : a matplotlib color specifier (string, tuple) or None
        The color for the fill. If None, the color of the line will be used.
    ax : a matplotlib Axes instance
        The axes to plot on. If None, the current pyplot axes will be used.
    Additional arguments are passed on to matplotlib's ``plot`` function.

    Returns
    -------
    line : a Line2D instance
        The line plotted.
    im : an AxesImage instance
        The transparent gradient clipped to just the area beneath the curve.
    """
    if ax is None:
        ax = plt.gca()

    line, = ax.plot(x, y, **kwargs)
    if fill_color is None:
        fill_color = line.get_color()

    zorder = line.get_zorder()
    alpha = line.get_alpha()
    alpha = 1.0 if alpha is 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, 0], xy, [xmax, 0], [xmin, 0]])
    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()