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
:
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.
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.
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]);
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.