如何在热图中注释和正确放置数字
Posted
技术标签:
【中文标题】如何在热图中注释和正确放置数字【英文标题】:How to annotate and correctly place numbers in a heatmap 【发布时间】:2021-12-08 13:17:39 【问题描述】:我遇到了热图问题。
我创建了以下函数来显示热图分析
data = [ 0.00662896, -0.00213044, -0.00156812, 0.01450994, -0.00875174, -0.01561342, -0.00694762, 0.00476027, 0.00470659]
def plot_heatmap(pathOut, data, title, fileName, precis=2, show=False):
from matplotlib import cm
fig = plt.figure()
n = int(np.sqrt(len(data)))
data = data.reshape(n,n)
heatmap = plt.pcolor(data,cmap=cm.YlOrBr)
xLabels = (np.linspace(1,n,n,dtype=int))
yLabels = (np.linspace(1,n,n,dtype=int))
xpos = np.linspace(1,n,n)-0.5
ypos = np.linspace(1,n,n)-0.5
for y in range(n):
for x in range(n):
plt.text(x + 0.5, y + 0.5, f'data[y, x]:.precisf',
horizontalalignment='center',
verticalalignment='center',
)
plt.colorbar(heatmap, format='%.2f')
plt.xticks(xpos,xLabels)
plt.yticks(ypos,yLabels)
plt.title(f'title')
if (show == False ):
plt.close(fig)
elif (show == True):
plt.show()
fig.savefig(f'pathOut/fileName.pdf', format='pdf')
当我调用该函数时,热图已创建但不正确,因为我想以特定精度显示值。我知道如何定义文本精度和比例精度,但是如何调整数据精度以生成正确的热图?
在附图中,我有 7 个等于 0 的单元格,用于我想要的精度,但使用的数据具有更大的精度,会产生不同的颜色。
【问题讨论】:
【参考方案1】: 使用seaborn.heatmap
更容易,其中包括注释和颜色条。 seaborn
是 matplotlib
的高级 API。
这大大减少了代码行数。
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
import seaborn as sns
def plot_heatmap(pathOut, fileName, data, title, precis=2, show=False):
n = int(np.sqrt(len(data)))
data = data.reshape(n, n)
xy_labels = range(1, n+1)
fig, ax = plt.subplots(figsize=(8, 6))
p = sns.heatmap(data=data, annot=True, fmt=f'.precisg', ax=ax,
cmap=cm.YlOrBr, xticklabels=xy_labels, yticklabels=xy_labels)
ax.invert_yaxis() # invert the axis if desired
ax.set_title(f'title')
fig.savefig(f'pathOut/fileName.pdf', format='pdf')
if (show == False ):
plt.close(fig)
elif (show == True):
plt.show()
data = np.array([ 0.00662896, -0.00213044, -0.00156812, 0.01450994, -0.00875174, -0.01561342, -0.00694762, 0.00476027, 0.00470659])
plot_heatmap('.', 'test', data, 'test', 4, True)
plt.txt
的 f 字符串不正确。将值 round
并将其转换为 str
类型会更容易。
str(round(data[x, y], precis))
而不是 f'data[y, x]:.precisf'
data[x, y]
应该是 data[y, x]
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
def plot_heatmap(pathOut, fileName, data, title, precis=2, show=False):
fig = plt.figure(figsize=(8, 6))
n = int(np.sqrt(len(data)))
data = data.reshape(n, n)
heatmap = plt.pcolor(data, cmap=cm.YlOrBr)
xLabels = (np.linspace(1,n,n,dtype=int))
yLabels = (np.linspace(1,n,n,dtype=int))
xpos = np.linspace(1,n,n)-0.5
ypos = np.linspace(1,n,n)-0.5
for y in range(n):
for x in range(n):
s = str(round(data[y, x], precis)) # added s for plt.txt and reverse x and y for data addressing
plt.text(x + 0.5, y + 0.5, s,
horizontalalignment='center',
verticalalignment='center',
)
plt.colorbar(heatmap, format=f'%.precisf') # add precis to the colorbar
plt.xticks(xpos,xLabels)
plt.yticks(ypos,yLabels)
plt.title(f'title')
fig.savefig(f'pathOut/fileName.pdf', format='pdf') # this should be before plt.show()
if (show == False ):
plt.close(fig)
elif (show == True):
plt.show()
# the function expects an array, not a list
data = np.array([ 0.00662896, -0.00213044, -0.00156812, 0.01450994, -0.00875174, -0.01561342, -0.00694762, 0.00476027, 0.00470659])
# function call
plot_heatmap('.', 'test', data, 'test', 4, True)
【讨论】:
感谢您的两个解决方案和提示。使用 round 函数,我们对 2 位小数的表示法有一点问题,结果只有一位小数,因为值接近于零,我们也因为同样的原因丢失了有关信号的信息。我发现了一个额外的事情是在heatmap = plt.pcolor(data, cmap=cm.YlOrBr, norm=mpl.colors.Normalize(vmin=np.amin(data)*1.5, vmax=np.amax(data)*1.5))
中定义限制。添加限制 f 字符串可以正常工作。以上是关于如何在热图中注释和正确放置数字的主要内容,如果未能解决你的问题,请参考以下文章
Plotly:如何在带注释的热图中舍入显示文本但在悬停时保持完整格式?