Scatter plot de Python. Taille et style du marqueur
j'ai un ensemble de données que je veux montrer, comme un nuage de points. Je veux que chaque point soit tracé comme un carré de taille dx
.
x = [0.5,0.1,0.3]
y = [0.2,0.7,0.8]
z = [10.,15.,12.]
dx = [0.05,0.2,0.1]
scatter(x,y,c=z,s=dx,marker='s')
le problème est que la taille s
que la fonction de dispersion lire est en points^2. Ce que j'aimerais c'est que chaque point soit représenté par un carré de superficie dx^2, où cette superficie est en unités "réelles", les unités de parcelle. J'espère que vous pouvez obtenir ce point.
j'ai aussi une autre question. L'éparpillement la fonction trace les marqueurs avec une bordure noire, comment puis-je laisser tomber cette option et n'ont pas de frontière?
4 réponses
Traduire de données utilisateur système de coordonnées à affichage système de coordonnées.
et utilisez edgecolors='none' pour tracer les visages sans contours.
import numpy as np
fig = figure()
ax = fig.add_subplot(111)
dx_in_points = np.diff(ax.transData.transform(zip([0]*len(dx), dx)))
scatter(x,y,c=z,s=dx_in_points**2,marker='s', edgecolors='none')
si vous voulez des marqueurs qui redimensionnent avec la taille de la figure, vous pouvez utiliser des patches:
from matplotlib import pyplot as plt
from matplotlib.patches import Rectangle
x = [0.5, 0.1, 0.3]
y = [0.2 ,0.7, 0.8]
z = [10, 15, 12]
dx = [0.05, 0.2, 0.1]
cmap = plt.cm.hot
fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal')
for x, y, c, h in zip(x, y, z, dx):
ax.add_artist(Rectangle(xy=(x, y),
color=cmap(c**2), # I did c**2 to get nice colors from your numbers
width=h, height=h)) # Gives a square of area h*h
plt.show()
noter que:
- les carrés ne sont pas centrés à
(x,y)
. x,y sont en fait les coords de le carré en bas à gauche. Je l'ai laissé ainsi pour simplifier mon code. Vous devrait utiliser(x + dx/2, y + dx/2)
. - la couleur provient du colormap chaud. J'ai utilisé z* * 2 pour donner couleur. vous devez également l'adapter à vos besoins
enfin votre deuxième question. Vous pouvez obtenir le bord des scatter marks en utilisant les arguments de mots clés edgecolor
ou edgecolors
. Il s'agit d'un argument de couleur matplotlib ou une séquence de tuples rgba, respectivement. Si vous définissez le paramètre à 'None', les bordures ne sont pas draw.
je pense que nous pouvons faire mieux avec une collection de patchs. Selon les documents:
ceci (PatchCollection) rend plus facile d'assigner une carte de couleur à un hétérogène collection de patchs.
cela peut également améliorer vitesse de pointage , car PatchCollection sera dessiner plus vite qu'un grand nombre de correctifs.
supposez que vous vous voulez tracer une dispersion de cercles avec un rayon donné dans l'Unité de données:
def circles(x, y, s, c='b', vmin=None, vmax=None, **kwargs):
"""
Make a scatter of circles plot of x vs y, where x and y are sequence
like objects of the same lengths. The size of circles are in data scale.
Parameters
----------
x,y : scalar or array_like, shape (n, )
Input data
s : scalar or array_like, shape (n, )
Radius of circle in data unit.
c : color or sequence of color, optional, default : 'b'
`c` can be a single color format string, or a sequence of color
specifications of length `N`, or a sequence of `N` numbers to be
mapped to colors using the `cmap` and `norm` specified via kwargs.
Note that `c` should not be a single numeric RGB or RGBA sequence
because that is indistinguishable from an array of values
to be colormapped. (If you insist, use `color` instead.)
`c` can be a 2-D array in which the rows are RGB or RGBA, however.
vmin, vmax : scalar, optional, default: None
`vmin` and `vmax` are used in conjunction with `norm` to normalize
luminance data. If either are `None`, the min and max of the
color array is used.
kwargs : `~matplotlib.collections.Collection` properties
Eg. alpha, edgecolor(ec), facecolor(fc), linewidth(lw), linestyle(ls),
norm, cmap, transform, etc.
Returns
-------
paths : `~matplotlib.collections.PathCollection`
Examples
--------
a = np.arange(11)
circles(a, a, a*0.2, c=a, alpha=0.5, edgecolor='none')
plt.colorbar()
License
--------
This code is under [The BSD 3-Clause License]
(http://opensource.org/licenses/BSD-3-Clause)
"""
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib.collections import PatchCollection
if np.isscalar(c):
kwargs.setdefault('color', c)
c = None
if 'fc' in kwargs: kwargs.setdefault('facecolor', kwargs.pop('fc'))
if 'ec' in kwargs: kwargs.setdefault('edgecolor', kwargs.pop('ec'))
if 'ls' in kwargs: kwargs.setdefault('linestyle', kwargs.pop('ls'))
if 'lw' in kwargs: kwargs.setdefault('linewidth', kwargs.pop('lw'))
patches = [Circle((x_, y_), s_) for x_, y_, s_ in np.broadcast(x, y, s)]
collection = PatchCollection(patches, **kwargs)
if c is not None:
collection.set_array(np.asarray(c))
collection.set_clim(vmin, vmax)
ax = plt.gca()
ax.add_collection(collection)
ax.autoscale_view()
if c is not None:
plt.sci(collection)
return collection
tous les arguments et mots clés (sauf marker
) de la fonction scatter
fonctionneraient de la même manière.
J'ai écris un gist y compris cercles , ellipses et carrés / rectangles . Si vous voulez une collection d'autres en forme, vous pourrait modifier vous-même.
si vous voulez tracer un colorbar juste exécuter colorbar()
ou passer l'objet de collection retourné à colorbar
fonction.
un exemple:
from pylab import *
figure(figsize=(6,4))
ax = subplot(aspect='equal')
#plot a set of circle
a = arange(11)
out = circles(a, a, a*0.2, c=a, alpha=0.5, ec='none')
colorbar()
#plot one circle (the lower-right one)
circles(1, 0, 0.4, 'r', ls='--', lw=5, fc='none', transform=ax.transAxes)
xlim(0,10)
ylim(0,10)
sortie:
pour rendre ce Python 3 compatible, j'ai ajouté l'extrait suivant du code
try:
basestring
except NameError:
basestring = str
de
Comment vérifier si la variable est une chaîne de compatibilité avec python 2 et 3
C'est nécessaire car basestring
n'est pas disponible en Python 3. Dans Python 2, le but de basestring
était d'inclure à la fois str
et unicode
. En Python 3 Il n'y a pas de distinction entre str
et unicode
, et c'est juste str
.