2
votes

Matplotlib - Déplacer l'étiquette de texte à droite par des points 'x'

J'ai le code suivant qui produit un graphique à bulles, puis ajoute les étiquettes sous forme de texte au tracé:

for i, txt in enumerate(labels):
    ax.annotate(txt, (x[i], y[i]), ha='center', va='center', )

 entrez la description de l'image ici p>

J'ai les étiquettes de texte centrées verticalement et horizontalement (c'est-à-dire les 1304,469, etc.), mais idéalement, je veux qu'elles soient décalées vers la droite pour qu'elles soient éloignées de la bulle. J'ai essayé ha = right , mais cela ne fait que le pousser un tout petit peu.

Puis-je utiliser quelque chose pour l'éloigner complètement de la bulle? C'est à dire. code Je peux le mettre comme suit for loop :

fig, ax = plt.subplots(figsize = (5,10))

# create data
x = [1,1,1,1,1,1,1,1,1,1]
y = ['A','B','C','D',
     'E','F','G','H','I','']
z = [10,20,80,210,390,1050,2180,4690,13040,0]

labels = [1,2,8,21,39,105,218,469,1304]

plt.xlim(0.9,1.1)

for i, txt in enumerate(labels):
    ax.annotate(txt, (x[i], y[i]), ha='center', va='center', )

plt.scatter(x, y, s=z*4000, c="#8C4799", alpha=0.3)


3 commentaires

ax.annotate (txt, (x [i] +1, y [i]), ha = 'center', va = 'center') ?


Hé, merci. Ça ne marche pas pour moi malheureusement


Je peux voir pourquoi ça n'a pas marché, ça sortait de mon intrigue. J'ai ignoré votre réponse car cela peut aider quelqu'un :) ... merci


3 Réponses :


2
votes

le paramètre xytext de ax.annotate vous permet de faire ceci:

fig, ax = plt.subplots(figsize = (5,10))

# create data
x = [1,1,1,1,1,1,1,1,1,1]
y = ['A','B','C','D',
     'E','F','G','H','I','']
z = [10,20,80,210,390,1050,2180,4690,13040,0]

labels = [1,2,8,21,39,105,218,469,1304]

plt.xlim(0.9,1.1)

for i, txt in enumerate(labels):
    ax.annotate(txt, (x[i], y[i]), ha='center', va='center', xytext=(1.05,y[i]) )

plt.scatter(x, y, s=z*4000, c="#8C4799", alpha=0.3)

Apporte ceci:

entrez la description de l'image ici

Modifier: si vous voulez que les libellés soient juste à droite de chaque cercle, vous devrez créer un tableau de positions puis parcourir il


2 commentaires

Hé, merci pour votre aide. J'ai essayé votre code, et c'était le même que mon code. Avez-vous le code que vous avez utilisé pour votre graphique? :)


Désolé, je ne sais pas pourquoi il a disparu. Maintenant c'est terminé!



2
votes

J'utiliserais simplement un pourcentage de décalage (20% par exemple) pour repositionner la coordonnée x du texte. De plus, vous pouvez désactiver le réglage manuel des limites x.

fig, ax = plt.subplots(figsize=(4, 10))

x = [1,1,1,1,1,1,1,1,1,1]
y = ['A','B','C','D',
     'E','F','G','H','I','']
z = [10,20,80,210,390,1050,2180,4690,13040,0]

labels = [1,2,8,21,39,105,218,469,1304]

for i, txt in enumerate(labels):
    ax.annotate(txt, (x[i]*1.2, y[i]), ha='center', va='center', )

plt.scatter(x, y, s=z*4000, c="#8C4799", alpha=0.3) 

 entrez la description de l'image ici


1 commentaires

Je vous remercie. Marche parfaitement. C'est une manière vraiment astucieuse de le faire, merci!



3
votes

Puisque la taille s des bulles est s = z * 4000 , le rayon d'une bulle est np.sqrt (z * 4000) / 2 code>. (Pour une explication, voir taille du marqueur de nuage de points ).

Vous créeriez donc une annotation qui est positionnée au centre des bulles en coordonnées de données et décalez-les de np.sqrt (z * 4000) / 2 en unités de points (ou peut-être 2 ou 3 points de plus pour que ça soit bien).

Cela serait fait en utilisant

import matplotlib.pyplot as plt
import numpy as np


fig, ax = plt.subplots(figsize = (5,10))

# create data
x = [1,1,1,1,1,1,1,1,1,1]
y = ['A','B','C','D',
     'E','F','G','H','I','']
z = [10,20,80,210,390,1050,2180,4690,13040,0]

labels = [1,2,8,21,39,105,218,469,1304]

plt.xlim(0.9,1.1)


sc = plt.scatter(x, y, s=z*4000, c="#8C4799", alpha=0.3)

for txt, size, xi, yi in zip(labels, sc.get_sizes(), x,y):
    ax.annotate(txt, xy=(xi,yi), xytext=(np.sqrt(size)/2+2, 0),
                textcoords="offset points",
                ha='left', va='center', )

plt.show()

Exemple complet:

annotate("text", xy=(x[i],y[i]), 
         xytext=(np.sqrt(z[i]*4000)/2+2, 0),  textcoords="offset points")

 entrez la description de l'image ici


0 commentaires