2015-10-15 35 views
8

Sto usando Seaborn in Python per creare una Heatmap. Sono in grado di annotare le celle con i valori passati, ma vorrei aggiungere annotazioni che indicano cosa significa la cella. Ad esempio, invece di vedere semplicemente 0.000000, mi piacerebbe vedere l'etichetta corrispondente, ad esempio "Foo" o 0.000000 (Foo).Custom Annotation Seaborn Heatmap

Il Seaborn documentation per la funzione mappa termica è un po 'criptico con il parametro che credo è la chiave qui:

annot_kws : dict of key, value mappings, optional 
    Keyword arguments for ax.text when annot is True. 

Ho provato a installare annot_kws a un dizionario degli alias per i valori, cioè, {'Foo' : -0.231049060187, 'Bar' : 0.000000}, ecc., ma sto ricevendo un AttributeError.

Ecco il mio codice (ho creato manualmente l'array di dati qui per riproducibilità):

data = np.array([[0.000000,0.000000],[-0.231049,0.000000],[-0.231049,0.000000]]) 
axs = sns.heatmap(data, vmin=-0.231049, vmax=0, annot=True, fmt='f', linewidths=0.25) 

Ecco il (di lavoro) in uscita quando io non uso il parametro annot_kws:

Working output

E qui l'analisi dello stack per quando faccio includono il annot_kws param:

--------------------------------------------------------------------------- 
AttributeError       Traceback (most recent call last) 
<ipython-input-57-38f91f1bb4b8> in <module>() 
    12 
    13 
---> 14 axs = sns.heatmap(data, vmin=min(uv), vmax=max(uv), annot=True, annot_kws=kws, linewidths=0.25) 
    15 concepts 

/opt/anaconda/2.3.0/lib/python2.7/site-packages/seaborn/matrix.pyc in heatmap(data, vmin, vmax, cmap, center, robust, annot, fmt, annot_kws, linewidths, linecolor, cbar, cbar_kws, cbar_ax, square, ax, xticklabels, yticklabels, mask, **kwargs) 
    272  if square: 
    273   ax.set_aspect("equal") 
--> 274  plotter.plot(ax, cbar_ax, kwargs) 
    275  return ax 
    276 

/opt/anaconda/2.3.0/lib/python2.7/site-packages/seaborn/matrix.pyc in plot(self, ax, cax, kws) 
    170   # Annotate the cells with the formatted values 
    171   if self.annot: 
--> 172    self._annotate_heatmap(ax, mesh) 
    173 
    174   # Possibly add a colorbar 

/opt/anaconda/2.3.0/lib/python2.7/site-packages/seaborn/matrix.pyc in _annotate_heatmap(self, ax, mesh) 
    138    val = ("{:" + self.fmt + "}").format(val) 
    139    ax.text(x, y, val, color=text_color, 
--> 140      ha="center", va="center", **self.annot_kws) 
    141 
    142  def plot(self, ax, cax, kws): 

/opt/anaconda/2.3.0/lib/python2.7/site-packages/matplotlib/axes/_axes.pyc in text(self, x, y, s, fontdict, withdash, **kwargs) 
    590   if fontdict is not None: 
    591    t.update(fontdict) 
--> 592   t.update(kwargs) 
    593   self.texts.append(t) 
    594   t._remove_method = lambda h: self.texts.remove(h) 

/opt/anaconda/2.3.0/lib/python2.7/site-packages/matplotlib/artist.pyc in update(self, props) 
    755    func = getattr(self, 'set_' + k, None) 
    756    if func is None or not six.callable(func): 
--> 757     raise AttributeError('Unknown property %s' % k) 
    758    func(v) 
    759    changed = True 

AttributeError: Unknown property tokenized 

Infine, kws, l'attributo che sto passando la linea nella traccia dello stack, è il dizionario e sarebbe un aspetto sostanzialmente in questo modo:

kws = {'Foo': -0.231049060187, 'Bar': 0.0} 

Spero che tutto ha un senso, e mi piacerebbe apprezzare ogni aiuto che chiunque può dare.

+0

Sei mai riuscito a risolvere questo problema? – Tom

+0

Purtroppo no .. – Tgsmith61591

risposta

12

Questa funzione è stata appena aggiunta nella versione recente di Seaborn 0.7.1.

Da Seaborn update history:

L'annot parametro di heatmap() accetta ora un set di dati rettangolare in aggiunta a un valore booleano.Se viene passato un set di dati, i suoi valori saranno utilizzati per le annotazioni, mentre il set di dati principale verrà utilizzato per i colori delle celle heatmap

Ecco un esempio

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

nota, fmt = '' è necessario se si utilizzano etichette non numeriche, poiché il valore predefinito è fmt = '. 2g' che ha senso solo per i valori numerici e comporterebbe un errore per le etichette di testo. enter image description here

2

aanot_kws in Seaborn uno scopo diverso, vale a dire, che fornisce l'accesso a modalità di visualizzazione annotazioni, piuttosto che quello che viene visualizzato

import matplotlib.pyplot as plt 
import seaborn as sns 

sns.set() 
fig, ax = plt.subplots(1,2) 
ata = np.array([[0.000000,0.000000],[-0.231049,0.000000],[-0.231049,0.000000]]) 
sns.heatmap(data, vmin=-0.231049, vmax=0, annot=True, fmt='f', annot_kws={"size": 15}, ax=ax[0]) 
sns.heatmap(data, vmin=-0.231049, vmax=0, annot=True, fmt='f', annot_kws={"size": 10}, ax=ax[1]); 

enter image description here

+0

Grazie @bushmanov. Conosci qualche modo per modificare le annotazioni? O è una causa persa? – Tgsmith61591

+0

@ Tgsmith61591 Grazie per l'accettazione. Le mappe di calore sono rappresentazioni di valori, quindi credo fermamente * che non ci siano modi intrinseci alla heatmap che permettano di estrarre l'etichetta inesistente 'Foo' dai dati sottostanti. Se hai sicuramente bisogno di allegare un'etichetta, guarderei a matplotlib come sovrascrive il testo nei suoi grafici. Dopotutto Seaborn è matplotlib. –

3

non credo questo è possibile nella versione attuale. Se si sono fino a un hack-y soluzione alternativa, è possibile effettuare le seguenti ...

# Create the 1st heatmap without labels 
sns.heatmap(data=df1, annot=False,) 

# create the second heatmap, which contains the labels, 
# turn the annotation on, 
# and make it transparent 
sns.heatmap(data=df2, annot=True, alpha=0.0) 

Si noti che si può avere un problema con la colorazione delle etichette di testo. Qui, ho creato una custom cmap per avere tutte le etichette uniformemente nere.

+0

Questo è quello che stavo cercando. Potresti aggiungere un esempio della tua combinazione di colori personalizzata? –