Comment ajouter colorbars pour les nuages de points créés comme cela?
- Je créer des nuages de points avec le code qui, en essence, qui va comme ceci
cmap = (matplotlib.color.LinearSegmentedColormap.
from_list('blueWhiteRed', ['blue', 'white', 'red']))
fig = matplotlib.figure.Figure(figsize=(4, 4), dpi=72)
ax = fig.gca()
for record in data:
level = record.level # a float in [0.0, 1.0]
marker = record.marker # one of 'o', 's', '^', '*', etc.
ax.scatter(record.x, record.y, marker=marker,
c=level, vmin=0, vmax=1, cmap=cmap, **otherkwargs)
# various settings of ticks, labels, etc. omitted
canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)
fig.set_canvas(canvas)
canvas.print_png('/path/to/output/fig.png')
Ma question est: est-ce
De quoi ai-je besoin d'ajouter le code ci-dessus pour obtenir une verticale de la barre de couleur (ce qui représente la palette de couleurs dans
cmap
) le long de la courbe du bord droit?
NOTE: je trouve Matplotlib absolument incompréhensible, et cela vaut pour à la fois son design ainsi que sa documentation. (Pas faute d'avoir essayé: j'ai mis beaucoup de temps, effort, et même un peu d'argent, en elle.) Ainsi j'apprécie le travail terminé, le code (même si c'est juste un jouet exemple), parce que probablement je ne vais pas être en mesure de remplir omis des détails ou corriger des bugs dans le code.
EDIT: j'ai corrigé une omission importante dans le code de "l'esquisse" ci-dessus, à savoir un record de marqueur spécifique de la spécification de chaque appel à ax.scatter
. C'est la raison pour la création du nuage de points avec plusieurs appels à ax.scatter
, bien que, certes, on peut au moins réduire le nombre d'appels à se disperser, à une par maker forme utilisée; par exemple,
for marker in set(record.marker for record in data):
X, Y, COLOR = zip(*((record.x, record.y, record.level)
for record in data if record.marker == marker))
ax.scatter(X, Y, marker=marker,
c=COLOR, vmin=0, vmax=1, cmap=cmap,
**otherkwargs)
J'ai essayé d'étendre le même tour à l'effondrement de tous les appels à ax.scatter
en un seul (par le passage d'une séquence de marqueurs comme la marker
argument), comme ceci:
X, Y, COLOR, MARKER = zip(*((record.x, record.y, record.level, record.marker)
for record in data))
ax.scatter(X, Y, marker=MARKER,
c=COLOR, vmin=0, vmax=1, cmap=cmap,
**otherkwargs)
...mais cela échoue. L'erreur va quelque chose comme ceci (après l'élagage de certains longs trajets):
Traceback (most recent call last):
File "src/demo.py", line 222, in <module>
main()
File "src/demo.py", line 91, in main
**otherkwargs)
File "<abbreviated-path>/matplotlib/axes.py", line 6100, in scatter
marker_obj = mmarkers.MarkerStyle(marker)
File "<abbreviated-path>/matplotlib/markers.py", line 113, in __init__
self.set_marker(marker)
File "<abbreviated-path>/matplotlib/markers.py", line 179, in set_marker
raise ValueError('Unrecognized marker style {}'.format(marker))
ValueError: Unrecognized marker style ('^', 'o', '^', '*', 'o', 's', 'o', 'o', '^', 's', 'o', 'o', '^', '^', '*', 'o', '*', '*', 's', 's', 'o', 's', 'o', '^', 'o', 'o', '*', '^', 's', '^', '^', 's', '*')
AFAICT, tcaswell la recette de nécessite réduire les appels à ax.scatter
à une seule, mais cette exigence semble en conflit avec mon exigence absolue pour plusieurs marqueur des formes dans le même nuage de points.
je ne pense pas qu'il y est une exigence pour de multiples marqueur formes dans
scatter
. juste de lui donner un seul marqueur pour chaque groupe de données.l'exigence est la mienne: j'ai besoin de plusieurs marqueurs des formes dans les nuages de points, je suis en train de faire.
voir ma réponse ci-dessous
Désolé j'ai été impoli, l'autre jour, j'étais dans une mauvaise humeur, et votre coup de gueule m'ont mis hors tension. Avez-vous ce tri?
OriginalL'auteur kjo | 2012-12-18
Vous devez vous connecter pour publier un commentaire.
Si vous devez utiliser un marqueur différent pour chaque jeu, vous avez à faire un peu de travail supplémentaire et la force de tous les
clims
être le même (sinon par défaut est mise à l'échelle du min/max de lac
données par un nuage de points).la
linewidths=0
définit la largeur de la frontière, sur la forme, je trouve que pour les petites formes de la bordure noire peut submerger la couleur de remplissage.Si vous avez seulement besoin d'une forme, vous pouvez faire tout cela avec un seul nuage de points, il n'est pas nécessaire de faire un distinct pour chaque passage dans la boucle.
une fois que vous avez toutes les données battu vers le bas dans un tableau 1D, faire le diagramme de dispersion, et de garder la valeur retournée:
Vous ensuite de faire votre barre de couleur et passer de l'objet renvoyé par
scatter
comme premier argument.Vous devez le faire afin que la couleur de la barre connaît la couleur de la carte (la carte et la plage) à utiliser.
fig.savefig()
une question ... quel est l'intérêt d'avoir dans les deux conditions (
if .... else
bloc) de la lignes = x.scatter(x,y,c=c,marker=markers[record],linewidths=0)
?OriginalL'auteur tacaswell
Je pense que votre meilleur pari sera de farcir vos données dans une pandas dataframe, et de parcourir l'ensemble de vos marqueurs de la sorte:
OriginalL'auteur Paul H
Je pense que cela devrait faire l'affaire. Je suis sûr que j'ai attrapé ce à partir de l'une des matplotlib exemples, un livre de cuisine tout à l'arrière, mais je n'arrive pas à le trouver maintenant...
la ligne
cb = plt.colorbar(cax=cax)
échoue avec l'erreurRuntimeError: No mappable was found to use for colorbar creation. First define a mappable such as an image (with imshow) or a contour set (with contourf).
Il peut être très simple pour résoudre ce problème, mais comme je l'ai expliqué dans un ajout à mon post, je suis un complet Matplotlib cancre...OriginalL'auteur Josha Inglis
La réponse à cette peut être à la seule parcelle d'un seul scatter, qui serait alors directement de permettre une colobar d'être créé.
Il s'agit de mettre des marqueurs dans le
PathCollection
créé par la dispersion a posteriori, mais il peut être facilement placé dans une fonction. Cette fonction provient de ma réponse sur une autre question, mais qui est directement applicable ici.En prenant les données de @PaulH de post ce serait semblable à
OriginalL'auteur ImportanceOfBeingErnest