【问题标题】:Imshow heatmap with array of arrays - problem with final plot/image带有数组数组的 Imshow 热图 - 最终绘图/图像的问题
【发布时间】:2022-01-07 03:12:51
【问题描述】:

我想绘制 imshow 热图,但最终图像看起来非常小且不成比例。 我的数据代表原子之间测量的距离(一个分子的 cca 10 个原子到另一个分子的 cca 30 个原子) - 结果是 array of arrays。我为说明准备了类似的输出,但是我的原始数据集更大:

import numpy as np
array1 = np.random.randint(20, size=30)
array2 = np.random.randint(20, size=30)
array3 = np.random.randint(20, size=30)
array4 = np.random.randint(20, size=30)
array5 = np.random.randint(20, size=30)
array6 = np.random.randint(20, size=30)
array7 = np.random.randint(20, size=30)
array8 = np.random.randint(20, size=30)
array9 = np.random.randint(20, size=30)
arrayOfArrays = np.array([array1, array2, array3, array4, array5, array6, array7, array8, array9])

然后我想制作热图来查看原子之间的距离,所以这是我的代码:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
im = ax.imshow(arrayOfArrays, origin='upper')

#this is here because I use this approach to define xticks and yticks in my original plot  - here I modified the code with "len(range(0,30))" but in my original plot there is number of atoms for which I measured the distances (something like n_atoms=len(dataset1))
n_1=len(range(0,30))
n_2=len(range(0,9))
tick_interval = 1
ax.set_yticks(np.arange(n_2)[::tick_interval])
ax.set_xticks(np.arange(n_1)[::tick_interval])

# colorbar
cbar = fig.colorbar(im)

使用此特定绘图创建的最终图像看起来已经很小,但包含我的原始数据的图像更小,我根本看不到里面的颜色。

如果有任何建议,或者应该编辑代码的哪一部分,我真的很感激?我尝试编辑图片大小,添加“插值”,“ascpect”...

【问题讨论】:

  • 你试过ax.imshow(..., aspect='auto')吗?

标签: python arrays numpy matplotlib imshow


【解决方案1】:

您也可以使用plt.pcolormesh() 来做与科学家的回答类似的事情,除了您不必担心您的纵横比。默认情况下,imshow 使块成为方形,就像图像中的像素一样。

改编自 Scientist 的代码:

nrows = 9
ncols = 30
minv = 0 # inclusive
maxv = 20 # exclusive
arrayofArrays = np.random.randint(low=minv, high=maxv, size=(nrows,ncols))

fig, ax = plt.subplots(figsize=(14,8)) # width and height in inches
im = ax.pcolormesh(arrayofArrays)

n_1 = np.arange(ncols)
n_2 = np.arange(nrows)
tick_interval = 1
ax.set_yticks(n_2[::tick_interval])
ax.set_xticks(n_1[::tick_interval])

# colourbar
cbar = fig.colorbar(im)

【讨论】:

    【解决方案2】:

    首先,没有必要像那样创建数组。相反,您可以使用列表推导式将所有内容集中在一行中:

    arrayOfArrays = np.array([np.random.randint(20, size=30) for _ in range(9)])
    

    我知道您可能正在使用数据集,但是,这对于随机创建数据很有用:3

    您的代码中还有一些其他冗余,您可以使用

    np.arange(30)
    

    而不是使用

    n_1 = len(range(0,30))
    np.arange(n_1)
    

    创建一个从 0 到 30 的整数列表

    Matplotlib 图形调整大小: 您可以调整图形的大小,绘制的所有内容

    fig.size_in_inches(10, 10)
    

    当我在您的代码中插入这一行并在 google colab 中运行它时,输出如下:

    如果要调整颜色条的大小,请使用fig.colorbar 中的shrink 参数,输出值为0.3:

    这是所有更改的代码:

    import numpy as np
    import matplotlib.pyplot as plt
    
    arrayOfArrays = np.array([np.random.randint(20, size=30) for _ in range(9)])
    
    fig, ax = plt.subplots()
    im = ax.imshow(arrayOfArrays, origin='upper')
    
    n_1=30
    n_2=9
    tick_interval = 1
    ax.set_yticks(np.arange(n_2)[::tick_interval]) # using np.arange directly
    ax.set_xticks(np.arange(n_1)[::tick_interval])
    
    fig.set_size_inches(10, 10) # setting figure size
    
    # colorbar
    cbar = fig.colorbar(im, shrink=0.3) # shrink parameter to adjust the size of colorbar 
    

    【讨论】:

    • 别管科学家的回答比我的好。
    【解决方案3】:

    我喜欢 TomiOck 的回答,但我相信 JohanC 是对的,因为您有一个数据集,其中列数多于行数。这可以通过将aspect='auto' 添加到imshow 命令来解决。

    这是我的尝试:

    import numpy as np
    nrows = 9
    ncols = 30
    minv = 0 # inclusive
    maxv = 20 # exclusive
    arrayofArrays = np.random.randint(low=minv, high=maxv, size=(nrows,ncols))
    

    您可以在一行numpy 中生成随机数据。

    import matplotlib.pyplot as plt
    
    fig, ax = plt.subplots(figsize=(14,8)) # width and height in inches
    im = ax.imshow(arrayOfArrays, origin='upper', aspect='auto', interpolation='None')
    
    n_1 = np.arange(ncols)
    n_2 = np.arange(nrows)
    tick_interval = 1
    ax.set_yticks(n_2[::tick_interval])
    ax.set_xticks(n_1[::tick_interval])
    
    # colourbar
    cbar = fig.colorbar(im)
    

    aspect='auto' 会拉伸您的图像以填充图形。 我还建议使用interpolation='None' 来绝对确保matplotlib 不会改变太多颜色(https://matplotlib.org/stable/gallery/images_contours_and_fields/interpolation_methods.html)。

    【讨论】:

    • 你是绝对正确的,这是更好的方法。我已经编辑了我的答案以纳入这一点。谢谢!
    猜你喜欢
    • 2020-11-25
    • 1970-01-01
    • 2016-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-21
    • 2011-05-24
    相关资源
    最近更新 更多