Matplotilb-如何使用对数标度为折线图设置颜色条

时间:2019-02-04 09:29:00

标签: python matplotlib colormap

我在将彩条添加到与幂律相对应的多条线的图中时遇到问题。

要为非图像绘图创建颜色栏,我添加了一个虚拟绘图(来自此处的答案:Matplotlib - add colorbar to a sequence of line plots)。

对于色标,刻度线与图的颜色不对应。

我尝试过更改颜色条的规范,我可以对其进行微调以使其在特定情况下准确无误,但是我通常不能这样做。

def plot_loglog_gauss():
    from matplotlib import cm as color_map
    import matplotlib as mpl

    """Creating the data"""
    time_vector = [0, 1, 2, 4, 8, 16, 32, 64, 128, 256]
    amplitudes = [t ** 2 * np.exp(-t * np.power(np.linspace(-0.5, 0.5, 100), 2)) for t in time_vector]

    """Getting the non-zero minimum of the data"""
    data = np.concatenate(amplitudes).ravel()
    data_min = np.min(data[np.nonzero(data)])

    """Creating K-space data"""
    k_vector = np.linspace(0,1,100)

    """Plotting"""
    number_of_plots = len(time_vector)
    color_map_name = 'jet'
    my_map = color_map.get_cmap(color_map_name)
    colors = my_map(np.linspace(0, 1, number_of_plots, endpoint=True))

    # plt.figure()
    # dummy_plot = plt.contourf([[0, 0], [0, 0]], time_vector, cmap=my_map)
    # plt.clf()

    norm = mpl.colors.Normalize(vmin=time_vector[0], vmax=time_vector[-1])
    cmap = mpl.cm.ScalarMappable(norm=norm, cmap=color_map_name)
    cmap.set_array([])


    for i in range(number_of_plots):
        plt.plot(k_vector, amplitudes[i], color=colors[i], label=time_vector[i])

    c = np.arange(1, number_of_plots + 1)
    plt.xlabel('Frequency')
    plt.ylabel('Amplitude')
    plt.yscale('symlog', linthreshy=data_min)
    plt.xscale('log')
    plt.legend(loc=3)

    ticks = time_vector
    plt.colorbar(cmap, ticks=ticks, shrink=1.0, fraction=0.1, pad=0)

    plt.show()

Plot generated

通过与图例进行比较,您可以看到刻度值与实际颜色不匹配。例如,颜色图中的绿色显示为128,而图例中的显示为红色。

实际结果应该是线性颜色的彩条。在色条上以固定间隔打勾(对应于不规则的时间间隔...)。当然,还要为刻度值校正颜色。

(最终该图包含许多图(len(time_vector)〜100),我降低了图的数量以进行说明并能够显示图例。)

要澄清一下,这就是我想要的结果。

Plot wanted

1 个答案:

答案 0 :(得分:1)

最重要的原理是使线条图和ScalarMappable的颜色保持同步。这意味着,线条的颜色不应取自独立的颜色列表,而应取自与要显示的色条相同的色图并使用相同的规格化。

然后,一个主要问题是决定如何处理0,而这SymLogNorm不能作为整体农业规范化的一部分。以下是一种变通方法,假设线性标度在0到2之间,并且使用import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np """Creating the data""" time_vector = [0, 1, 2, 4, 8, 16, 32, 64, 128, 256] amplitudes = [t ** 2 * np.exp(-t * np.power(np.linspace(-0.5, 0.5, 100), 2)) for t in time_vector] """Getting the non-zero minimum of the data""" data = np.concatenate(amplitudes).ravel() data_min = np.min(data[np.nonzero(data)]) """Creating K-space data""" k_vector = np.linspace(0,1,100) """Plotting""" cmap = plt.cm.get_cmap("jet") norm = mpl.colors.SymLogNorm(2, vmin=time_vector[0], vmax=time_vector[-1]) sm = mpl.cm.ScalarMappable(norm=norm, cmap=cmap) sm.set_array([]) for i in range(len(time_vector)): plt.plot(k_vector, amplitudes[i], color=cmap(norm(time_vector[i])), label=time_vector[i]) #c = np.arange(1, number_of_plots + 1) plt.xlabel('Frequency') plt.ylabel('Amplitude') plt.yscale('symlog', linthreshy=data_min) plt.xscale('log') plt.legend(loc=3) cbar = plt.colorbar(sm, ticks=time_vector, format=mpl.ticker.ScalarFormatter(), shrink=1.0, fraction=0.1, pad=0) plt.show() 在上面的对数标度上。

{{1}}

enter image description here