0
votes

Changer l'ordre des entrées pour une légende de la carte Geopandas Choropleth

Je sais une certaine valeur catégorique sur la carte d'une ville. La ligne de code que j'utilise pour tracer est la suivante:

import geopandas as gpd
import numpy as np
import matplotlib.pyplot as plt 

gdf=gpd.read_file('.../USA_adm1.shp')
clusters=np.random.randint(0,4, size=52)
gdf['cluster']=clusters
clusdict={1: 'lower-middle', 2: 'upper-middle', 3: 'upper', 0: 'lower'}
gdf['cluster']=gdf['cluster'].map(clusdict)

fig = plt.figure(figsize=(12, 12))
ax = plt.gca()
gdf.plot(column='cluster',cmap='viridis', categorical=True, legend=True, ax=ax)


5 commentaires

Lorsque vous dites "je les reçois toujours affichés dans un ordre différent", que dépend de cette commande? S'il s'agit de l'occurrence des catégories dans le Dataframe, vous pouvez probablement simplement le trier à votre goût avant de comploter.


Je suppose que les entrées sont triées par ordre alphabétique (car elles sont), mais je n'ai aucune idée de la façon de contrôler cela. Dans le GDF, ils sont tous mélangés.


Je crains que vous ayez besoin de fournir un exemple minimal reproductible ici. Peut-être Ce peut être ajusté à votre cas?


@ImportudesBeingingNest J'ai ajouté un exemple vérifiable. Malheureusement, il y a un fichier à télécharger, mais après cela, il est assez simple de reproduire le problème.


D'accord, super. Quelle est votre ordre désiré dans la légende maintenant? Cela a-t-il à voir avec les chiffres de 0 à 3?


3 Réponses :


0
votes

En supposant que vous avez 4 légendes, vous pouvez faire ce qui suit pour les définir dans n'importe quel ordre que vous aimez. Le code suivant montre comment les mettre dans l'ordre suivant (à l'aide de l'index): 0, 2, 3, 1.

ici Ax code> est l'objet Axis que vous avez défini à l'aide de AXE = plt.gca () code> p> xxx pré>

Permettez-moi de vous donner un exemple: P>

Commandement par défaut Strong> p> xxx pré>

 Entrez la description de l'image ici p>

Commande manuelle modifiée manuellement strong> p>

order = [0, 2, 3, 1]
handles,labels = ax.get_legend_handles_labels()
handles = [handles[i] for i in order]
labels = [labels[i] for i in order]
ax.legend(handles, labels, fontsize=16)


4 commentaires

J'ai déjà essayé ax.get_legend_handles_labels () , mais il renvoie des listes vides. Probablement parce que la légende ici n'est pas un attribut Ax , mais il est appelé avec légende = true dans la fonction TRACE. Mais je ne suis pas sûr de cela. Seule une chose certaine est que les poignées et les étiquettes sont des listes vides.


Hmm. Dans ce cas, fournissez un exemple minimal, complet et vérifiable


hein. Ce n'est pas facile car je ne peux pas partager les données et créer un géodatafratafratafratafraframe "factice" n'est pas immédiat. Je vais essayer depuis un moment


J'ai ajouté un exemple vérifiable.



2
votes

La mauvaise nouvelle est que les catégories de légendes produites par les Geopandas sont triées et ceci est codé en dur ( Voir le code source ici ).

Une solution est donc d'avoir la colonne catégorique telle que si elle est triée, elle correspondrait à la commande souhaitée. L'utilisation d'entiers semble bien pour cela. Ensuite, on peut remplacer les noms dans la légende, une fois qu'il est produit dans le bon ordre. xxx

 Entrez la description de l'image ici


1 commentaires

OK cool. Donc, si l'ordre souhaité n'est pas 0-1-2-3 (BC, par exemple, il s'agit de catégories qui résultent d'un algorithme de clustering, qui ne les attribuent pas avec un but classement) la solution serait d'identifier le classement par moi-même et ensuite pour appliquer cette fonction 2 fois: le premier à assigner le classement des étiquettes 0-1-2-3, de sorte que la légende devienne un enregistrement d'entiers triés, puis à nouveau pour donner les noms souhaités à ce qu'il soit triché Étiquettes. Merci beaucoup!



1
votes

Je devais modifier la réponse acceptée (la deuxième ligne de la fonction) à partir de @importancesBeingernest un peu pour le faire fonctionner (peut-être avoir été mises à jour depuis),

import geopandas as gpd
import numpy as np
import matplotlib.pyplot as plt 

gdf=gpd.read_file('data/USA_adm/USA_adm1.shp')
clusters=np.random.randint(0,4, size=52)
gdf['cluster']=clusters
clusdict={1: 'lower-middle', 2: 'upper-middle', 3: 'upper', 0: 'lower'}

fig = plt.figure(figsize=(12, 12))
ax = plt.gca()
gdf.plot(column='cluster',cmap='viridis', categorical=True, legend=True, ax=ax)

def replace_legend_items(legend, mapping):
    for txt in legend.get_texts():
        for k,v in mapping.items():
            if txt.get_text() == str(k):
                txt.set_text(v)

replace_legend_items(ax.get_legend(), clusdict)

plt.show()


0 commentaires