web-dev-qa-db-fra.com

Carte thermique Seaborn d'annotation personnalisée

J'utilise Seaborn dans Python pour créer une carte thermique. Je peux annoter les cellules avec les valeurs transmises, mais je voudrais ajouter des annotations qui signifient ce que signifie la cellule. Par exemple, au lieu de voir simplement 0.000000, Je voudrais voir l'étiquette correspondante, par exemple "Foo" ou 0.000000 (Foo).

La documentation Seaborn pour la fonction heatmap est un peu cryptique avec le paramètre qui, je crois, est la clé ici:

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

J'ai essayé de définir annot_kws Sur un dictionnaire des alias des valeurs, c'est-à-dire {'Foo' : -0.231049060187, 'Bar' : 0.000000}, Etc., mais j'obtiens une AttributeError.

Voici mon code (j'ai créé manuellement le tableau de données ici pour la reproductibilité):

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)

Voici la sortie (qui fonctionne) lorsque je n'utilise pas le paramètre annot_kws:

Working output

Et ici, la trace de la pile pour quand je inclut le paramètre annot_kws:

---------------------------------------------------------------------------
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

Enfin, kws, l'attribut que je passe dans la ligne dans la trace de la pile, est le dictionnaire et il ressemblerait essentiellement à ceci:

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

J'espère que tout a un sens et j'apprécierais toute aide que quiconque puisse apporter.

15
Tgsmith61591

Cette fonctionnalité vient d'être ajoutée dans la version récente de Seaborn 0.7.1.

De Historique des mises à jour de Seaborn :

Le paramètre annot de heatmap () accepte désormais un jeu de données rectangulaire en plus d'une valeur booléenne. Si un jeu de données est transmis, ses valeurs seront utilisées pour les annotations, tandis que le jeu de données principal sera utilisé pour les couleurs des cellules de la carte thermique

Voici un exemple

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 = '')

Remarque, fmt = '' est nécessaire si vous utilisez des étiquettes non numériques, car la valeur par défaut est fmt = '. 2g' qui n'a de sens que pour les valeurs numériques et entraînerait une erreur pour les étiquettes de texte. enter image description here

35
ojy

aanot_kws dans Seaborn sert un but différent, à savoir, il donne accès à comment les annotations sont affichées, plutôt que ce que s'affiche

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

4
Sergey Bushmanov

Je ne pense pas que cela soit possible dans la version actuelle. Si vous envisagez une solution de contournement, vous pouvez effectuer les opérations suivantes ...

# 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)

Notez que vous pouvez avoir un problème avec la coloration de vos étiquettes de texte. Ici, j'ai créé un cmap personnalisé pour que toutes les étiquettes soient uniformément noires.

4
user2489252