【问题标题】:How to display multiple annotations in Seaborn Heatmap cells?如何在 Seaborn Heatmap 单元格中显示多个注释?
【发布时间】:2019-08-02 03:03:09
【问题描述】:

我希望 seaborn 热图在热图的每个单元格中显示多个值。为了清楚起见,这是我想看到的手动示例:

data = np.array([[0.000000,0.000000],[-0.231049,0.000000],[-0.231049,0.000000]])
labels =  np.array([['A\nExtra Stuff','B'],['C','D'],['E','F']])
fig, ax = plt.subplots()
ax = sns.heatmap(data, annot = labels, fmt = '')

这里作为示例,让 seaborn.heat 在单元格中显示 flightsRoundUp 值。

import matplotlib.pyplot as plt
import seaborn as sns
sns.set()

def RoundUp(x):
    return int(np.ceil(x/10)*10)

# Load the example flights dataset and conver to long-form
flights_long = sns.load_dataset("flights")
flights = flights_long.pivot("month", "year", "passengers")
flightsRoundUp =  flights.applymap(RoundUp)

# Draw a heatmap with the numeric values in each cell
f, ax = plt.subplots(figsize=(9, 6))
sns.heatmap(flights, annot=flightsRoundUp, fmt="", linewidths=.5, ax=ax)

在所有单元格中同时显示flightsRoundUpflights 的最佳方式是什么?类似于上面的第一个手动示例,但对于所有单元格都以类似矢量的方式...

【问题讨论】:

  • 你的意思是this
  • 不完全是。但这帮助我将问题减少到能够通过np.core.defchararray.add(X, Y) 组合 X 和 Y,我还没有完全弄清楚。以下是 X 和 Y 示例:X = pd.DataFrame({'a':[1, 2, np.nan], 'b':[10, np.nan, 30]}) Y = pd.DataFrame({'A':[11, 222, np.nan], 'B':[110, np.nan, 330]})
  • 如果元素都是没有任何nan的字符串。您分享的上述链接将是我问题的确切解决方案。
  • 你试过...add(X.values.astype(str), Y.values.astype(str))吗?
  • @ImportanceOfBeingErnest 这行得通。谢谢!

标签: python seaborn heatmap


【解决方案1】:

Rotail 的回答对我不起作用,我在应用那个 lambda 函数时出错。

但是,我找到了一个解决方案,该解决方案利用了 seaborn 将连续数字相互叠加的事实。您所要做的就是使用一次调用 heatmap 来建立图形,然后调用每个注释。使用 annot_kws arg 确保文本不会相互覆盖。

X = pd.DataFrame({'a':[1, 2, 3], 'b':[4, 5, 6]})
Y = pd.DataFrame({'A':['A', 'B', 'C'], 'B':['E', 'F', 'G']})
Z = pd.DataFrame({'A':['(Extra Stuff)', '(Extra Stuff)', '(Extra Stuff)'], 'B':['(Extra Stuff)', '(Extra Stuff)', '(Extra Stuff)']})

sns.heatmap(X, annot=False)
sns.heatmap(X, annot=Y, annot_kws={'va':'bottom'}, fmt="", cbar=False)
sns.heatmap(X, annot=Z, annot_kws={'va':'top'}, fmt="", cbar=False)

【讨论】:

    【解决方案2】:

    以下对我也有用:

    X = pd.DataFrame({'a':[1, 2, np.nan], 'b':[10, 20, 30]})
    Y = pd.DataFrame({'A':[11, 222, np.nan], 'B':[110, np.nan, 330]})
    
    # convert to string
    X_value_ann = (X).astype('|S5').reset_index()
    Y_value_ann = (Y).astype('|S5').reset_index()
    
    # define () and new line to glue on later
    br = np.char.array(pd.DataFrame('\n(', index=X_value_ann.index, columns=X_value_ann.columns))
    cl = np.char.array(pd.DataFrame(')', index=X_value_ann.index, columns=X_value_ann.columns))
    
    # convert to chararray
    X_value_ann = np.char.array(X_value_ann)
    Y_value_ann = np.char.array(Y_value_ann)
    
    # glue and reshape
    my_annotation = pd.DataFrame(X_value_ann+br+Y_value_ann+cl)
    my_annotation = my_annotation.applymap(lambda x: x.decode('utf-8')) 
    my_annotation = my_annotation.drop(columns=[0])
    my_annotation
    

    【讨论】:

      【解决方案3】:

      您应该能够设置fmt="" 并使用适当的"\n" 格式化标签以具有多行注释。

      import pandas as pd
      import numpy as np
      import seaborn as sns
      import matplotlib.pyplot as plt
      
      np.random.seed(0)
      sns.set_theme()
      uniform_data = np.random.rand(4, 4)
      fig,ax = plt.subplots(figsize=(50,20))
      
      uniform_data_labels = \[\]
      for i in uniform_data:
          tmp_arr=\[\]
          for j in i:
              tmp_arr.append('Example\nExample')
          uniform_data_labels.append(tmp_arr)
          
      sns.heatmap(uniform_data, vmin=0, vmax=1, annot=uniform_data_labels ,ax=ax,fmt="",annot_kws={"fontsize":30})
      plt.show()
      

      1

      【讨论】:

        猜你喜欢
        • 2020-08-26
        • 1970-01-01
        • 1970-01-01
        • 2020-11-28
        • 2018-08-16
        • 2021-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多