我正在尝试使用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()
理想上,我想产生这样的内容
我的绘图程序产生的效果看起来不太好,彩色图块和注释框都不连续。因此,感谢您的帮助。
以下方法使用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()