matplotlib standard de la palette d'utilisation
Je suis en utilisant matplotlib 1.3.0 et j'ai le texte suivant:
import matplotlib.pyplot as plt
cmap = plt.cm.jet
plt.contourf([[.12, .2], [.8, 2]], levels=[0, .1, .3, .5, 1, 3], cmap=cmap, vmin=0, vmax=3)
plt.colorbar()
qui produit:
Le peu que je ne comprends pas, c'est là où toutes les autres couleurs vont? Ce que je comprends, en spécifiant vmin=0
, vmax=3
puis la couleur de la barre d'utiliser la gamme complète de cmap
comme dans cette image:
qui est produit sans donner la vmin
, vmax
et levels
arguments. Donc... ce qui me manque ici?
EDIT 1
En réponse à tom10 & tcaswell. J'aurais attendu qu'elle soit comme vous le dites, mais... malheureusement, il ne l'est pas. Jetez un oeil à ceci:
plt.contourf([[.12, .2], [.8, 3.2]], levels=[0, .1, .3, .5, 1, 3], cmap=cmap, vmin=0, vmax=3)
plt.colorbar()
avec:
Peut-être pour clarifier un peu tout ça: dire que j'ai données et les caractéristiques importantes sont autour de 0,1, mais il y a quelques autour de 3 disons. Donc, je lui donne un levels=[0, 0.005, 0.075, 0.1, 0.125, 0.15, 0.2, 1, 2.5, 2.75, 3, 3.25]
et vmin=0, vmax=3.25
. Maintenant, je m'attends à voir la gamme complète de couleurs, mais au lieu de toutes les données importantes des points de 0,005 à 0,125 à la fin dans la région bleue (en utilisant la norme plt.cm.jet
carte de la couleur). Ce que je veux dire, je suppose que c'est... si je donne levels=[0, 1, 2, 3], vmin=0, vmax=3
de certaines données qui va de 0 à 3-je m'attendre à en voir de toutes les couleurs dans la couleur de la carte, mais si je donne levels=[0, 0.9, 0.1, 0.11, 1, 3], vmi=0, vmax=3
je m'attends à la même chose, pour voir de toutes les couleurs dans la couleur de la carte, à l'exception associées aux intervalles, à la place je vois le tas de blues de la coloration de l'0-0.11 région et un peu de vert /jaune coloration de l'autre partie de la région. Espérons que cela en fait... un peu clair.
EDIT 2
Le même phénomène se produit même si je ne donne pas tout norm
ou vmin, vmax
.
MODIFIER 3
Se référant à tcaswell du commentaire, de se comporter comme ça... du moins pour moi, est contre-intuitif. Je m'attendais à ce que la couleur serait indépendante des données de points dans un sens. Je m'attends à ce que la gamme complète de couleurs de la palette de couleurs serait utilisé tout le temps (sauf quand le vmin, vmax
sont plus grands ou plus petits que la levels
min, max). En d'autres termes, en regardant ce code que j'ai fait un tout à l'arrière (Python 3):
import matplotlib.colors as mc
def addNorm(cmapData):
cmapData['norm'] = mc.BoundaryNorm(cmapData['bounds'], cmapData['cmap'].N)
return True
def discretize(cmap, bounds):
resCmap = {}
resCmap['cmap'] = mc.ListedColormap( \
[cmap(i/len(bounds[1:])) for i in range(len(bounds[1:]))]
)
resCmap['bounds'] = bounds
addNorm(resCmap)
return resCmap
ensuite l'utiliser comme:
levels = [0, .1, .3, .5, 1, 3]
cmapData = discretize(plt.cm.jet, bounds=levels)
plt.contourf([[.12, .2], [.8, 3.2]], levels=levels, cmap=cmapData['cmap'], norm=cmapData['norm'])
plt.colorbar()
qui donne la parcelle où l'on peut distinguer les caractéristiques (0.1-0.5), c'est à dire qu'ils ne sont plus dans le bleu de la région à l'aide de la méthode ci-dessus avec plt.cm.jet
:
Je veux dire, je sais que j'ai résolu ce problème, et un temps de retour trop... mais ma question je suppose que c'est... comment se fait par défaut dans matplotlib n'est-ce pas? Je me serais attendu à être de cette façon... ou peut-être est-ce juste une configuration /argument /quelque chose pour activer cette fonction par défaut que je suis absent?
OK, je pense que j'ai eu l'idée de comment cette carte des couleurs par défaut sont utilisés (et je ne suis pas gêné par le blanc), mais... alors est-il un moyen de rendre les couleurs se comportent comme des je devrais attendre? c'est à dire. à l'aide d'un palette avec des couleurs à partir de c0 c8 disons que, pour des raisons de simplicité, mais je suis encore en se référant à la par défaut carte des couleurs): lorsque j'ai mis
levels=[0, 0.09, 0.1, 0.11, 3]
je m'attends à utiliser [c0 (de 0-0.09), c2 (0.09-0.1), c4 (0.09-0.1), c6 (0.1-0.11), c8 (0.11 - 0.3)] au lieu d'utiliser [c0 (0-0.09), c1 (0.09-0.1), c2 (0.1-0.11), c6 (0.11-3)]. Espérons que cela a du sens...très bien, mais ce n'est pas ce que vous avez fait. La carte de la couleur ne sait rien au sujet de votre niveaux, tous il sait comment faire pour convertir un scalaire -> une couleur de façon linéaire entre
vmin
et vmax
. Regardez dans la liste des cartes en couleurs.matplotlib.org/api/...
Voir les commentaires ici: github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/... pour savoir comment les couleurs sont définies
OriginalL'auteur razvanc | 2013-09-03
Vous devez vous connecter pour publier un commentaire.
Après avoir joué un peu, il semble que la réponse à cette question est plus facile que j'ai jamais pensé. Juste quelques explications en premier. Lors de la lecture de la documentation sur la normalisation des classes de
matplotlib.colors
j'ai pensé que... eh bien,matplotlib.colors.BoundaryNorm
doit être utilisée ici! mais quelque chose est faux comme vous pouvez le voir dans l'exemple suivant:qui donne ceci:
et c'est évidemment quelque chose que nous ne voulons pas! Et je me disais... pourquoi auriez-vous à donner au constructeur de
BoundaryNorm
le nombre de couleurs à utiliser?... Ne devrait pasBoundaryNorm
utiliser la totalité de la palette de couleurs? Et puis ça m'a frappé, avec juste un peu de changement pour le code ci-dessus:et nous obtenons:
ce qui est exactement ce que nous voulons!
Ou vous nous pouvons faire:
Sens vous l'impression de vous comprendre, de cas d'utilisation et boundry norme, pouvez-vous écrire de la documentation pour cela? Il serait utile afin d'améliorer la doc de chaînes ou d'ajouter un exemple de la galerie.
Oui, je vais écrire un peu de documentation sur ce, j'espère que tôt ou tard.
OriginalL'auteur razvanc
La couleur de la remplir de la région est repris par le point milieu des deux lignes de remplissage entre (iirc). Le jaune que vous voyez est la cartographie des
2
en vertu de la couleur de la carte et les limites que vous avez définies.Si vous voulez faire correspondre la couleur par région indice, faire un peu de monkey patching:
Vous pouvez probablement faire mieux et de supprimer le passage par 1/2.
Vous pouvez également rejoindre en et suffit de changer la couleur de l'existant contours. Il semble que vous ayez besoin de changer les valeurs de
out.cvalues
et ensuite appelerout.changed()
sur l'objet.Moins destructrice version serait d'écrire une coutume
norm
par sous-classingmatplotlib.colors.Normalize
, voir colors.py pour un modèle.Oui, c'est cool :D... je ne savais même pas que vous pouvez le faire... attribuer vos propres cultivés à la maison fonctions permettant de modifier les fonctionnalités de base comme ça. Oui, j'aurais attendu qu'elle soit fondée sur l'indice des niveaux plutôt que les données de l' :)... pour être en mesure de mieux visualiser les régions d'intérêt (ie. lorsque les données sont fortement non-linéaires). Merci!
aussi regarder
LogNorm
ou de l'écriture personnalisée norme fonctions. Que peut-être moins de perturbations dans le long terme.Je ne savais pas que vous pouvez écrire personnalisé norme fonctions... une autre chose de nouveau... ce jours est pleine de surprises 🙂
comme par exemple, en utilisant ce qui rend vos scripts fondamentalement unsharable que cela modifie la façon dont
mpl
se comporte. Vous pouvez être intelligent, de conserver une référence à l'original et de le restaurer plus tard.OriginalL'auteur tacaswell
La valeur maximale de vos données est
2
. Dans la parcelle en question vous définissezvmax=3
.Plus en détail,
vmax
définit la gamme de couleurs utilisées dans la cartographie. Depuis c'est beaucoup plus grand que votre plage de données, lorsque vous tracer les données, vous ne voyez pas la gamme complète de couleurs. C'est encore compliquée par le petit nombre delevels
que vous avez choisi, ce qui n'est pas de vous montrer toutes les couleurs sont disponibles, depuis la barre de couleur montre qu'une couleur unique pour l'ensemble de 1 à 3, de gamme, de nouveau, en masquant les couleurs disponibles au-delà de 2.OriginalL'auteur tom10
En fait, je pense que la meilleure solution pour le moment est situé à cet endroit:
http://protracted-matter.blogspot.ie/2012/08/nonlinear-colormap-in-matplotlib.html
Il définit cette petite classe qui permet de résoudre tous les problèmes:
Le script a été développé à l'origine par un gars nommé Robert Hetland. Tous les détails sont dans le lien ci-dessus.
matplotlib
utilise. Le bon endroit pour mettre du comportement non-linéaire est dans leNormalize
fonctions.Oui, vous avez raison, par exemple avec ce que j'ai remarqué que
set_over
par exemple ne fonctionne pas. Mais encore, je n'ai pas le temps d'aller dans les détails de la normalisation de la classe (car il ne dispose pas d'exemples sur la façon de prolonger) et c'est juste plus facile pour ce dont j'ai besoin.Je refusés cette réponse que j'ai enfin trouvé une alternative satisfaisante à l'aide de
BoundaryNorm
qui j'ai documenté dans l'acceptation de réponse.OriginalL'auteur razvanc