【问题标题】:How to fix the heatmap plotted in python which seems way off from the scatterplot如何修复在 python 中绘制的热图似乎与散点图相去甚远
【发布时间】:2019-11-12 05:35:45
【问题描述】:

我想绘制一个热图,以便在散点图中更好地可视化分布模式,但我在生成热图时遇到了一些问题。 y 轴上的数据从 0 到 15,x 从 0 到 7。

我参考了下面关于如何生成热图的帖子并编写了以下代码,这似乎给了我一个散点图,这似乎与我希望从散点图中得到的完全不同。

Generate a heatmap in MatPlotLib using a scatter data set

import matplotlib.pyplot as plt
import numpy as np
from matplotlib import cm as CM

x = [0.3178, 2.0857, 2.5922, 0.088, 0.3, 0.4006, 1.0241, 0.1913, 0.56, 1.1828, 2.6879, 5.8044, 0.3593, 1.8732, 10.8003, 0.3457, 1.7003, 0.1677, 0.7442, 1.5731, 0.4927, 0.4143, 0.558, 0.2486, 0.3009, 0.163, 2.645, 4.1364, 13.8043, 3.9997, 0.258, 0.78, 10.3991, 0.2425, 0.3335, 4.8002, 0.3529, 5.9263, 0.151, 0.34, 0.1146, 13.6505, 2.8802, 3.2738, 0.5562, 0.5067, 1.5142, 2.0373, 2.5427, 12.1005]
y = [4.4903, 6.8879, 5.6211, 5.1128, 1.8125, 4.9716, 2.6847, 5.3744, 6.5254, 3.875, 3.6667, 2.0, 6.9811, 6.0501, 6.0, 6.8478, 5.0, 5.3676, 3.403, 6.1015, 6.8793, 4.7684, 3.5934, 2.6224, 5.9319, 1.8191, 3.0554, 3.5207, 3.6786, 3.0, 5.9041, 1.9128, 6.3333, 5.4949, 5.7135, 6.0, 5.5348, 3.0, 5.2644, 5.8111, 1.093, 4.0, 7.0, 6.0, 3.8684, 4.8, 1.5283, 6.6932, 7.0, 4.0]

# plot the scatter_plot
xposition = [0,7]
plt.figure()
plt.plot(y,x,'r^', label='series_1',markersize=12)
plt.gcf().set_size_inches(11.7, 8.27)
ax = plt.gca()
ax.tick_params(axis = 'both', which = 'major', labelsize = 16)
for xc in range(0,xposition[-1]+1):
    ax.axvline(x=xc, color='darkgrey', linestyle='--', linewidth = 2)

plt.xlabel('x', fontsize=18)
plt.ylabel('y', fontsize=18)
plt.xlim(xposition)
plt.ylim([0,15])
plt.legend(loc='upper right',fontsize = 'x-large')

# plot the heatmap
plt.figure()
heatmap, xedges, yedges = np.histogram2d(y, x, bins=50)
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]

plt.clf()
plt.imshow(heatmap.T, extent=extent, interpolation='nearest', origin='lower')
plt.pcolormesh(xedges, yedges, heatmap, cmap=CM.RdBu_r, vmin=-7, vmax=7)
plt.gcf().set_size_inches(11.7, 8.27)
plt.show()

对于结果,首先,热图的绘图大小似乎与散点图不同,尽管我指定它们相同。其次,热图似乎与散点图中似乎聚集在右下角的模式不匹配。请告知我应该在哪里修改以获得正确的热图。谢谢。

【问题讨论】:

    标签: python python-3.x heatmap


    【解决方案1】:

    下面的代码似乎可以修复它。你犯了 3 个错误。

    1. 您使图形的大小相同,而不是轴。 我为散点图添加了一个 set_aspect 以使纵横比相等,与热图中的相同。

    2. 您绘制了一个 imshow,然后在其上绘制了一个 pcolormesh(您不需要两者)。

    3. 出于某种原因,pcolormesh 期望热图相对于 imshow 所需的内容进行转置。我转了。

    
    
        import matplotlib.pyplot as plt
        import numpy as np
        from matplotlib import cm as CM
    
        x = [0.3178, 2.0857, 2.5922, 0.088, 0.3, 0.4006, 1.0241, 0.1913, 0.56, 1.1828, 2.6879, 5.8044, 0.3593, 1.8732, 10.8003, 0.3457, 1.7003, 0.1677, 0.7442, 1.5731, 0.4927, 0.4143, 0.558, 0.2486, 0.3009, 0.163, 2.645, 4.1364, 13.8043, 3.9997, 0.258, 0.78, 10.3991, 0.2425, 0.3335, 4.8002, 0.3529, 5.9263, 0.151, 0.34, 0.1146, 13.6505, 2.8802, 3.2738, 0.5562, 0.5067, 1.5142, 2.0373, 2.5427, 12.1005]
        y = [4.4903, 6.8879, 5.6211, 5.1128, 1.8125, 4.9716, 2.6847, 5.3744, 6.5254, 3.875, 3.6667, 2.0, 6.9811, 6.0501, 6.0, 6.8478, 5.0, 5.3676, 3.403, 6.1015, 6.8793, 4.7684, 3.5934, 2.6224, 5.9319, 1.8191, 3.0554, 3.5207, 3.6786, 3.0, 5.9041, 1.9128, 6.3333, 5.4949, 5.7135, 6.0, 5.5348, 3.0, 5.2644, 5.8111, 1.093, 4.0, 7.0, 6.0, 3.8684, 4.8, 1.5283, 6.6932, 7.0, 4.0]
    
        # plot the scatter_plot
        xposition = [0,7]
        plt.figure()
        plt.plot(y,x,'r^', label='series_1',markersize=12)
        plt.gcf().set_size_inches(11.7, 8.27)
        ax = plt.gca()
        ax.tick_params(axis = 'both', which = 'major', labelsize = 16)
        for xc in range(0,xposition[-1]+1):
            ax.axvline(x=xc, color='darkgrey', linestyle='--', linewidth = 2)
    
        plt.xlabel('x', fontsize=18)
        plt.ylabel('y', fontsize=18)
        plt.xlim(xposition)
        plt.ylim([0,15])
        plt.legend(loc='upper right',fontsize = 'x-large')
        plt.gca().set_aspect('equal')
    
        heatmap, xedges, yedges = np.histogram2d(y, x, bins=50)
        extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
    
    
        # plot the heatmap
        plt.figure()
        #plt.imshow(heatmap.T, extent=extent, interpolation='nearest', origin='lower')
        plt.pcolormesh(xedges, yedges,  heatmap.transpose(), cmap=CM.RdBu_r, vmin=-7, vmax=7)
        plt.gcf().set_size_inches(11.7, 8.27)
        plt.gca().set_aspect('equal')
        plt.show()
    
    

    另外,你为什么不尝试使用 subplot 而不是下面示例中的两个数字?虽然添加颜色条可能会遇到一些问题,但这是可以解决的。

    import matplotlib.pyplot as plt
    import numpy as np
    from matplotlib import cm as CM
    
    x = [0.3178, 2.0857, 2.5922, 0.088, 0.3, 0.4006, 1.0241, 0.1913, 0.56, 1.1828, 2.6879, 5.8044, 0.3593, 1.8732, 10.8003, 0.3457, 1.7003, 0.1677, 0.7442, 1.5731, 0.4927, 0.4143, 0.558, 0.2486, 0.3009, 0.163, 2.645, 4.1364, 13.8043, 3.9997, 0.258, 0.78, 10.3991, 0.2425, 0.3335, 4.8002, 0.3529, 5.9263, 0.151, 0.34, 0.1146, 13.6505, 2.8802, 3.2738, 0.5562, 0.5067, 1.5142, 2.0373, 2.5427, 12.1005]
    y = [4.4903, 6.8879, 5.6211, 5.1128, 1.8125, 4.9716, 2.6847, 5.3744, 6.5254, 3.875, 3.6667, 2.0, 6.9811, 6.0501, 6.0, 6.8478, 5.0, 5.3676, 3.403, 6.1015, 6.8793, 4.7684, 3.5934, 2.6224, 5.9319, 1.8191, 3.0554, 3.5207, 3.6786, 3.0, 5.9041, 1.9128, 6.3333, 5.4949, 5.7135, 6.0, 5.5348, 3.0, 5.2644, 5.8111, 1.093, 4.0, 7.0, 6.0, 3.8684, 4.8, 1.5283, 6.6932, 7.0, 4.0]
    
    # plot the scatter_plot
    xposition = [0,7]
    plt.figure()
    ax1 = plt.subplot(1,2,1)
    plt.plot(y,x,'r^', label='series_1',markersize=12)
    plt.gcf().set_size_inches(11.7, 8.27)
    ax1.tick_params(axis = 'both', which = 'major', labelsize = 16)
    for xc in range(0,xposition[-1]+1):
        ax1.axvline(x=xc, color='darkgrey', linestyle='--', linewidth = 2)
    
    plt.xlabel('x', fontsize=18)
    plt.ylabel('y', fontsize=18)
    plt.xlim(xposition)
    plt.ylim([0,15])
    plt.legend(loc='upper right',fontsize = 'x-large')
    plt.gca().set_aspect('equal')
    
    heatmap, xedges, yedges = np.histogram2d(y, x, bins=50)
    extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
    
    
    # plot the heatmap
    #plt.figure()
    #plt.imshow(heatmap.T, extent=extent, interpolation='nearest', origin='lower')
    ax2 = plt.subplot(1,2,2,sharex=ax1,sharey=ax1)
    heatmap_copy = heatmap.transpose()
    heatmap_copy[heatmap_copy==0] = np.nan
    plt.pcolormesh(xedges, yedges,  heatmap_copy, cmap=CM.RdBu_r, vmin=-7, vmax=7)
    ax2.set_aspect('equal')
    plt.xlabel('x', fontsize=18)
    plt.ylabel('y', fontsize=18)
    plt.ylim([0,3])
    ax2.tick_params(axis = 'both', which = 'major', labelsize = 16)
    for xc in range(0,xposition[-1]+1):
        ax2.axvline(x=xc, color='darkgrey', linestyle='--', linewidth = 2)
    plt.show()
    

    【讨论】:

    • 感谢您的回复。它有效:) 但是,为什么热图中的背景是灰色的?我可以改变它吗?此外,我尝试通过在“plt.ylabel”之后添加“plt.ylim([0,3])”来仅放大 y 轴的下部,但它似乎不起作用。请问我应该在哪里改?
    • @MollyZhou “背景”是颜色图中对应于 0 的颜色。如果您希望它在缺少数据的情况下为白色,则需要将热图中的这些位置设置为 nan 而不是 0。我编辑了第二个脚本(带有子图的那个)以显示白色背景。另外,我在 ylabel 之后添加了 ply.ylim([0,3]) 并且它可以工作。你确定你在正确的数字上做吗?当正确的数字是当前数字时。如果你喜欢这个答案,你应该喜欢并接受。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 2021-09-01
    • 2019-01-08
    • 2016-09-10
    • 1970-01-01
    • 2019-05-19
    相关资源
    最近更新 更多