如何将Matplotlib imshow()与带注释的框一起使用以生成带标签的2d图

问题描述 投票:0回答:1

我正在尝试使用imshow()生成稀疏数组的二维图,并使用plt.text()将其与文本框重叠。我想出了另一个选择,使用plt.scatter()。在第二种情况下,彩色图块和文本框太小,无法缩放。在第一种情况下,由imshow()和文本框生成的彩色图块的大小具有不连贯的大小,并且只有在使用对话框窗口的缩放功能的情况下,图看起来才能很好。下面的代码对此进行了说明。

import matplotlib.pyplot as plt
import matplotlib.colors as colors
import numpy as np

#https://matplotlib.org/gallery/images_contours_and_fields/image_annotated_heatmap.html

P=[1, 4, 11, 18, 20, 39, 40, 41, 41, 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, 72, 72, 73, 73, 73, 74, 74, 74, 74, 74, 74, 75, 75, 75, 71]
N=[2, 3, 11, 19, 25, 49, 48, 50, 54, 101, 102, 103, 103, 106, 106, 100, 103, 106, 106, 107, 109, 105, 106, 109, 104, 107, 109, 110, 111, 112, 108, 109, 109, 101]
B=np.random.rand(34)

# crate the array to use with imshow()
A=np.zeros((max(N)+1,max(N)+1))
for i,j,k in zip(N,P,B):
     A[i,j]=k

def plot_map(N,P,A):     
    fig, ax = plt.subplots()     
    plt.imshow(A,norm=colors.LogNorm(),cmap='jet',origin='lower')
    plt.colorbar()
    for n,p in zip(N,P):
            ax.text(p,n, "\n%s\n%s\n%5.1E"%(p,n,A[n,p]),
                ha="center", va="center",
            bbox=dict(fc="none",boxstyle = "square"))
    plt.tight_layout()
    plt.show()

# call the plot function
plot_map(N,P,A)    

# attempt tow using plt.scatter() 
plt.scatter(N,P,c=B,marker='s',s=70,norm=colors.LogNorm(),cmap='jet')
for n,p in zip(N,P):
         plt.text(n,p, "\n%s\n%s"%(p,n), size=3,
             va="center", ha="center", multialignment="left",
             bbox=dict(fc="none",boxstyle = "square"))
plt.colorbar()
plt.show()

理想上,我想产生这样的内容

enter image description here

我的绘图程序产生的效果看起来不太好,彩色图块和注释框都不连续。因此,感谢您的帮助。

python-3.x matplotlib imshow
1个回答
0
投票

以下方法使用mplcursors在屏幕上显示信息,并且还保存可以打印的图像文件。

当在A4纸上打印时,每个小方块大约为2x2毫米,因此,好的打印机和镜面玻璃可能会有所帮助。您可能要尝试使用fontsize。

在屏幕上,当单击一个小方块时,mplcursors显示一个弹出注释。放大时,需要双击以免干扰缩放UI。 mplcursors也具有“悬停”模式,但是放大时不显示任何信息。

一些代码演示它如何工作:

mplcursors

左侧是放大并双击正方形时在屏幕上的外观。右边是放大时要打印的图像的外观。

import matplotlib.pyplot as plt import matplotlib.colors as colors import mplcursors import numpy as np P = [1, 4, 11, 18, 20, 39, 40, 41, 41, 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, 72, 72, 73, 73, 73, 74, 74, 74, 74, 74, 74, 75, 75, 75, 71] N = [2, 3, 11, 19, 25, 49, 48, 50, 54, 101, 102, 103, 103, 106, 106, 100, 103, 106, 106, 107, 109, 105, 106, 109, 104, 107, 109, 110, 111, 112, 108, 109, 109, 101] B = np.random.rand(34) # crate the array to use with imshow() A = np.zeros((max(N) + 1, max(N) + 1)) for i, j, k in zip(N, P, B): A[i, j] = k fig, ax = plt.subplots(figsize=(21, 15)) img = ax.imshow(A, norm=colors.LogNorm(), cmap='jet', origin='lower') plt.colorbar(img) for n, p in zip(N, P): plt.text(p, n, "%s\n%s\n%5.1E"%(p,n,A[n,p]), size=2, va="center", ha="center", multialignment="left") cursor = mplcursors.cursor(img, hover=False) @cursor.connect("add") def on_add(sel): i,j = sel.target.index if A[i][j] == 0: sel.annotation.set_visible(False) else: sel.annotation.set_text(f'P: {j}\nN: {i}\n{A[i][j]:.3f}') plt.tight_layout() plt.savefig('test.png', dpi=300) plt.show()

© www.soinside.com 2019 - 2024. All rights reserved.