pyplot Taille du marqueur de dispersion

dans le document du plan de sondage pour le nuage de points:

matplotlib.pyplot.scatter (x, y, s=20, c='b', marker='o', cmap=None, norm=None, vmin=None, vmax=None, alpha=None, linewidths=None, faceted=True, verts=None, hold=None, **kwargs)

Le marqueur de taille

s: taille en points^2. Il est un scalaire ou un tableau de la même longueur que x et y.

Quel genre d'unité est points^2 ? Ça veut dire quoi? Est-ce que s=100 signifie 10 pixel x 10 pixel ?

en gros, j'essaie de faire des diagrammes de dispersion avec différentes tailles de marqueurs, et je veux comprendre ce que signifie le nombre s .

220
demandé sur LWZ 2013-02-12 11:37:29

6 réponses

cela peut être une façon quelque peu confuse de définir la taille, mais vous spécifiez essentiellement la zone du marqueur. Cela signifie que, pour doubler la largeur (ou la hauteur) du marqueur, vous devez augmenter s d'un facteur de 4. [parce que A = W H = > (2W) (2H)=4A]

Il y a une raison, cependant, que la taille des marqueurs est définie de cette manière. En raison de l'échelle de la zone que le carré de la largeur, doublant le largeur apparaît en effet à augmenter la taille de plus d'un facteur 2 (en fait, il augmente par un facteur de 4). Pour voir ce considérons les deux exemples suivants et la sortie qu'ils produisent.

# doubling the width of markers
x = [0,2,4,6,8,10]
y = [0]*len(x)
s = [20*4**n for n in range(len(x))]
plt.scatter(x,y,s=s)
plt.show()

donne

enter image description here

Remarquez comment la taille augmente très rapidement. Si à la place nous avons

# doubling the area of markers
x = [0,2,4,6,8,10]
y = [0]*len(x)
s = [20*2**n for n in range(len(x))]
plt.scatter(x,y,s=s)
plt.show()

donne

enter image description here

maintenant, la taille apparente des marqueurs augmente de façon à peu près linéaire et intuitive.

quant à la signification exacte de ce qu'est un "point", il est assez arbitraire aux fins de tracé, vous pouvez simplement mettre à l'échelle toutes vos tailles par une constante jusqu'à ce qu'ils semblent raisonnables.

Espérons que cette aide!

Edit: (en réponse au commentaire de @Emma)

c'est c'est probablement une formulation confuse de ma part. La question posée sur le doublement de la largeur d'un cercle de sorte que dans la première image pour chaque cercle (que nous nous déplaçons de gauche à droite) c'est la largeur est le double de la précédente donc pour la zone c'est une exponentielle avec la base 4. De même le deuxième exemple chaque cercle a superficie double le dernier qui donne une exponentielle avec la base 2.

cependant c'est le deuxième exemple (où nous mesurons la surface) que le doublement zone semble faire le cercle deux fois plus grand à l'œil. Ainsi si nous voulons qu'un cercle apparaisse un facteur de n plus grand nous augmenterions la surface d'un facteur n pas le rayon ainsi la taille apparente se balance linéairement avec la zone.

258
répondu Dan 2015-04-22 16:40:36

parce que d'autres réponses prétendent que s indique la zone du marqueur, j'ajoute cette réponse à clearify que ce n'est pas nécessairement le cas.

Taille en points^2

l'argument s dans plt.scatter dénote le markersize**2 . Comme le dit la documentation

s : scalaire ou array_like, de la forme (n, ), option

taille en points^2. La valeur par défaut est rcParams ['lines.markersize"] * * 2.

cela peut être pris au pied de la lettre. Pour obtenir un marqueur qui est x points large, vous devez quadriller ce nombre et le donner à l'argument s .

ainsi la relation entre le markersize d'un tracé de ligne et l'argument de taille de dispersion est le carré. Afin de produire un scatter marqueur de la même taille qu'une parcelle de marqueur de taille 10 points que vous appelleriez donc scatter( .., s=100) .

enter image description here

import matplotlib.pyplot as plt

fig,ax = plt.subplots()

ax.plot([0],[0], marker="o",  markersize=10)
ax.plot([0.07,0.93],[0,0],    linewidth=10)
ax.scatter([1],[0],           s=100)

ax.plot([0],[1], marker="o",  markersize=22)
ax.plot([0.14,0.86],[1,1],    linewidth=22)
ax.scatter([1],[1],           s=22**2)

plt.show()

Connexion "zone",

alors pourquoi d'autres réponses et même la documentation parlent-elles de" zone "quand il s'agit du paramètre s ?

bien sûr, les unités des points**2 sont des unités de surface.

  • Pour le cas particulier d'un carré marqueur, marker="s" , l'aire du marqueur est en effet directement la valeur du paramètre s .
  • Pour un cercle, l'aire du cercle est area = pi/4*s .
  • pour les autres marqueurs, il n'y a peut-être même pas de relation évidente avec l'aire du marqueur.

enter image description here

dans tous les cas cependant l'aire du marqueur est proportionnel au paramètre s . C'est la motivation pour l'appeler "zone" même si dans la plupart des cas, ce n'est pas vraiment le cas.

spécifier la taille des marqueurs de dispersion en termes de quantité qui est proportionnelle à la surface du marqueur fait à ce jour sens car il s'agit de la zone du marqueur qui est perçue lors de la comparaison de différentes taches plutôt que sa longueur ou son diamètre latéral. C'est-à-dire: doubler la quantité sous-jacente devrait doubler la la zone du marqueur.

enter image description here

Quels sont les points?

jusqu'à présent, la réponse à ce que la taille d'un scatter marqueur moyen est donné en unités de points. Les points sont souvent utilisés en typographie, où les polices sont spécifiées en points. Aussi les linewidths sont souvent spécifiés en points. La taille standard des points dans matplotlib est de 72 points par pouce (ppi) - 1 point est donc 1/72 pouces.

il pourrait être utile de pouvoir spécifier des tailles en pixels au lieu de points. Si le chiffre dpi est aussi 72, un point est un pixel. Si le chiffre dpi est différent (par défaut matplotlib est fig.dpi=100 ),

1 point == fig.dpi/72. pixels

alors que la taille du marqueur de dispersion en points serait donc différente pour différentes figures dpi, on pourrait produire un marqueur de 10 par 10 pixels^2, qui aurait toujours le même nombre de pixels couverts:

enter image description here enter image description here enter image description here

import matplotlib.pyplot as plt

for dpi in [72,100,144]:

    fig,ax = plt.subplots(figsize=(1.5,2), dpi=dpi)
    ax.set_title("fig.dpi={}".format(dpi))

    ax.set_ylim(-3,3)
    ax.set_xlim(-2,2)

    ax.scatter([0],[1], s=10**2, 
               marker="s", linewidth=0, label="100 points^2")
    ax.scatter([1],[1], s=(10*72./fig.dpi)**2, 
               marker="s", linewidth=0, label="100 pixels^2")

    ax.legend(loc=8,framealpha=1, fontsize=8)

    fig.savefig("fig{}.png".format(dpi), bbox_inches="tight")

plt.show() 
78
répondu ImportanceOfBeingErnest 2017-11-21 00:49:20

il s'agit de la zone du marqueur. Je veux dire que vous avez s1 = 1000 et puis s2 = 4000 , la relation entre le rayon de chaque cercle est: r_s2 = 2 * r_s1 . Voir le tracé suivant:

plt.scatter(2, 1, s=4000, c='r')
plt.scatter(2, 1, s=1000 ,c='b')
plt.scatter(2, 1, s=10, c='g')

enter image description here

j'ai eu le même doute quand j'ai vu le poteau, donc j'ai fait cet exemple puis j'ai utilisé une règle sur l'écran pour mesurer les rayons.

12
répondu Joaquin 2016-04-20 19:40:43

vous pouvez utiliser markersize pour spécifier la taille du cercle dans la méthode de tracé

import numpy as np
import matplotlib.pyplot as plt

x1 = np.random.randn(20)
x2 = np.random.randn(20)
plt.figure(1)
# you can specify the marker size two ways directly:
plt.plot(x1, 'bo', markersize=20)  # blue circle with size 10 
plt.plot(x2, 'ro', ms=10,)  # ms is just an alias for markersize
plt.show()

à Partir de ici

enter image description here

11
répondu zhaoqing 2017-04-13 06:54:20

j'ai également essayé d'utiliser 'scatter' initialement à cette fin. Après un peu de temps perdu - j'ai adopté la solution suivante.

import matplotlib.pyplot as plt
input_list = [{'x':100,'y':200,'radius':50, 'color':(0.1,0.2,0.3)}]    
output_list = []   
for point in input_list:
    output_list.append(plt.Circle((point['x'], point['y']), point['radius'], color=point['color'], fill=False))
ax = plt.gca(aspect='equal')
ax.cla()
ax.set_xlim((0, 1000))
ax.set_ylim((0, 1000))
for circle in output_list:    
   ax.add_artist(circle)

enter image description here

Ceci est basé sur une réponse à cette question

2
répondu Ike 2017-06-05 18:20:46

si la taille des cercles correspond au carré du paramètre dans s=parameter , alors Assignez une racine carrée à chaque élément que vous ajoutez à votre tableau de taille, comme ceci: s=[1, 1.414, 1.73, 2.0, 2.24] tel que quand il prend ces valeurs et les renvoie, leur augmentation de taille relative sera la racine carrée de la progression carrée, qui renvoie une progression linéaire.

si je devais quadriller chacun comme il obtient la sortie à la parcelle: output=[1, 2, 3, 4, 5] . Essayez de liste interprétation: s=[numpy.sqrt(i) for i in s]

1
répondu user34028 2016-11-05 19:37:50