使用 Pandas 数据帧中的值注释热图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21024066/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Annotate heatmap with value from Pandas dataframe
提问by jonas
I would like to annotate a heatmap with the values that I pass from a dataframe into the function below. I have looked at matplotlib.text but have not been able to get the values from my dataframe in a desired way in my heatmap. I have pasted in my function for generating a heatmap below, after that my dataframe and the output from the heatmap call. I would like to plot each value from my dataframe in the center of each cell in the heatmap.
我想用我从数据帧传递到下面的函数的值来注释热图。我查看了 matplotlib.text,但无法在我的热图中以所需的方式从我的数据框中获取值。我在下面粘贴了用于生成热图的函数,然后是我的数据框和热图调用的输出。我想在热图中每个单元格的中心绘制我的数据框中的每个值。
Function for generating a heatmap:
生成热图的函数:
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
def heatmap_binary(df,
edgecolors='w',
#cmap=mpl.cm.RdYlGn,
log=False):
width = len(df.columns)/7*10
height = len(df.index)/7*10
fig, ax = plt.subplots(figsize=(20,10))#(figsize=(width,height))
cmap, norm = mcolors.from_levels_and_colors([0, 0.05, 1],['Teal', 'MidnightBlue'] ) # ['MidnightBlue', Teal]['Darkgreen', 'Darkred']
heatmap = ax.pcolor(df ,
edgecolors=edgecolors, # put white lines between squares in heatmap
cmap=cmap,
norm=norm)
ax.autoscale(tight=True) # get rid of whitespace in margins of heatmap
ax.set_aspect('equal') # ensure heatmap cells are square
ax.xaxis.set_ticks_position('top') # put column labels at the top
ax.tick_params(bottom='off', top='off', left='off', right='off') # turn off ticks
plt.yticks(np.arange(len(df.index)) + 0.5, df.index, size=20)
plt.xticks(np.arange(len(df.columns)) + 0.5, df.columns, rotation=90, size= 15)
# ugliness from http://matplotlib.org/users/tight_layout_guide.html
from mpl_toolkits.axes_grid1 import make_axes_locatable
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", "3%", pad="1%")
plt.colorbar(heatmap, cax=cax)
plt.show()
Herre is an example of My dataframe :
这是我的数据框的示例:
dataframe :
0-5 km / h 5-40 km / h 40-80 km / h 80-120 km / h \
NORDIC 0.113955 0.191888 0.017485 -0.277528
MIDDLE EU 0.117903 0.197084 -0.001447 -0.332677
KOREA 0.314008 0.236503 -0.067174 -0.396518
CHINA 0.314008 0.236503 -0.067174 -0.396518
120-160 km / h 160-190 km / h 190 km / h
NORDIC -0.054365 0.006107 0.002458
MIDDLE EU 0.002441 0.012097 0.004599
KOREA -0.087191 0.000331 0.000040
CHINA -0.087191 0.000331 0.000040
Generating the heatmap:
生成热图:
heatmap_binary(dataframe)


Any ideas?
有任何想法吗?
Update to clarify my problem
更新以澄清我的问题
I tried the proposed solution from question which has the result I'm looking for: how to annotate heatmap with text in matplotlib?However, I still have a problem using the matplotlib.text function for positioning the values in the heatmap: Here is my cod for trying this solution:
我尝试了问题中提出的解决方案,该解决方案得到了我正在寻找的结果: 如何在 matplotlib 中使用文本注释热图?但是,使用 matplotlib.text 函数在热图中定位值仍然存在问题:这是我尝试此解决方案的代码:
import matplotlib.pyplot as plt
import numpy as np
data = dataframe.values
heatmap_binary(dataframe)
for y in range(data.shape[0]):
for x in range(data.shape[1]):
plt.text(data[y,x] +0.05 , data[y,x] + 0.05, '%.4f' % data[y, x], #data[y,x] +0.05 , data[y,x] + 0.05
horizontalalignment='center',
verticalalignment='center',
color='w')
#plt.colorbar(heatmap)
plt.show()
added plot: (different coloring but same problem)

添加的情节:(不同的颜色,但同样的问题)

回答by 8one6
The values you were using for your coordinates in your forloop were screwed up. Also you were using plt.colorbarinstead of something cleaner like fig.colorbar. Try this (it gets the job done, with no effort made to otherwise cleanup the code):
您在for循环中用于坐标的值被搞砸了。您还使用plt.colorbar了诸如fig.colorbar. 试试这个(它完成了工作,无需努力以其他方式清理代码):
def heatmap_binary(df,
edgecolors='w',
#cmap=mpl.cm.RdYlGn,
log=False):
width = len(df.columns)/7*10
height = len(df.index)/7*10
fig, ax = plt.subplots(figsize=(20,10))#(figsize=(width,height))
cmap, norm = mcolors.from_levels_and_colors([0, 0.05, 1],['Teal', 'MidnightBlue'] ) # ['MidnightBlue', Teal]['Darkgreen', 'Darkred']
heatmap = ax.pcolor(df ,
edgecolors=edgecolors, # put white lines between squares in heatmap
cmap=cmap,
norm=norm)
data = df.values
for y in range(data.shape[0]):
for x in range(data.shape[1]):
plt.text(x + 0.5 , y + 0.5, '%.4f' % data[y, x], #data[y,x] +0.05 , data[y,x] + 0.05
horizontalalignment='center',
verticalalignment='center',
color='w')
ax.autoscale(tight=True) # get rid of whitespace in margins of heatmap
ax.set_aspect('equal') # ensure heatmap cells are square
ax.xaxis.set_ticks_position('top') # put column labels at the top
ax.tick_params(bottom='off', top='off', left='off', right='off') # turn off ticks
ax.set_yticks(np.arange(len(df.index)) + 0.5)
ax.set_yticklabels(df.index, size=20)
ax.set_xticks(np.arange(len(df.columns)) + 0.5)
ax.set_xticklabels(df.columns, rotation=90, size= 15)
# ugliness from http://matplotlib.org/users/tight_layout_guide.html
from mpl_toolkits.axes_grid1 import make_axes_locatable
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", "3%", pad="1%")
fig.colorbar(heatmap, cax=cax)
Then
然后
df1 = pd.DataFrame(np.random.choice([0, 0.75], size=(4,5)), columns=list('ABCDE'), index=list('WXYZ'))
heatmap_binary(df1)
gives:
给出:


回答by JayaZ
This functionality is provided by the seabornpackage. It can produce maps like
此功能由seaborn包提供。它可以生成像
An example usage of seabornis
seaborn 的一个示例用法是
import seaborn as sns
sns.set()
# Load the example flights dataset and conver to long-form
flights_long = sns.load_dataset("flights")
flights = flights_long.pivot("month", "year", "passengers")
# Draw a heatmap with the numeric values in each cell
sns.heatmap(flights, annot=True, fmt="d", linewidths=.5)
回答by Joe Kington
This is because you're using plt.textafter you've added another axes.
这是因为您在plt.text添加另一个轴之后使用。
The state machine will plot on the currentaxes, and after you've added a new one with divider.append_axes, the colorbar's axes is the current one. (Just calling plt.colorbarwill not cause this, as it sets the current axes back to the original one afterwards if it creates the axes itself. If a specific axes object is passed in using the caxkwarg, it doesn't reset the "current" axes, as that's not what you'd normally want.)
状态机将绘制在当前轴上,并且在您添加了一个新轴之后divider.append_axes,颜色条的轴是当前轴。(只是调用plt.colorbar不会导致这种情况,因为如果它自己创建轴,它会将当前轴设置回原来的轴。如果使用caxkwarg传入特定的轴对象,它不会重置“当前”轴,因为那不是您通常想要的。)
Things like this are the main reason that you'll see so many people advising that you use the OO interface to matplotlib instead of the state machine interface. That way you know which axes object that you're plotting on.
像这样的事情是你会看到这么多人建议你使用面向 matplotlib 的 OO 接口而不是状态机接口的主要原因。这样你就知道你正在绘制哪个轴对象。
For example, in your case, you could have heatmap_binaryreturn the axobject that it creates, and the plot using ax.textinstead of plt.text(and similar for the other plotting methods).
例如,在您的情况下,您可以heatmap_binary返回ax它创建的对象,并使用ax.text代替plt.text(和其他绘图方法类似)的绘图。
回答by Fariliana Eri
You also can use plotly.figure_factoryto create heatmap from DataFrame, but you have convertit into list.
您还可以使用plotly.figure_factory创建热图的数据帧,但你必须转换它成列表。
import plotly.figure_factory as ff
z = [your_dataframe].values.tolist()
x = [your_dataframe].columns.tolist()
y = [your_dataframe].index.tolist()
fig = ff.create_annotated_heatmap(z, x=x, y=y, annotation_text=z, colorscale='viridis')
# for add annotation into Heatmap
for i in range(len(fig.layout.annotations)):
fig.layout.annotations[i].font.size = 12
# show your Heatmap
fig.show()

