étonnamment, je n'ai pas trouvé de description claire sur la manière de dessiner un cercle avec matplotlib.pyplot (veuillez ne pas utiliser de pylab) en prenant comme centre de saisie (x, y) et rayon r. J'ai essayé quelques variantes de ceci:
import matplotlib.pyplot as plt
circle=plt.Circle((0,0),2)
# here must be something like circle.plot() or not?
plt.show()
... mais ça ne fonctionne toujours pas.
Vous devez l'ajouter à un axe. Un Circle
est une sous-classe d'un Artist
, et un axes
a une méthode add_artist
.
Voici un exemple de cela:
import matplotlib.pyplot as plt
circle1 = plt.Circle((0, 0), 0.2, color='r')
circle2 = plt.Circle((0.5, 0.5), 0.2, color='blue')
circle3 = plt.Circle((1, 1), 0.2, color='g', clip_on=False)
fig, ax = plt.subplots() # note we must use plt.subplots, not plt.subplot
# (or if you have an existing figure)
# fig = plt.gcf()
# ax = fig.gca()
ax.add_artist(circle1)
ax.add_artist(circle2)
ax.add_artist(circle3)
fig.savefig('plotcircles.png')
Cela donne la figure suivante:
Le premier cercle est à l'origine, mais par défaut, clip_on
correspond à True
, de sorte que le cercle est tronqué chaque fois qu'il dépasse de axes
. Le troisième cercle (vert) montre ce qui se passe lorsque vous ne coupez pas la Artist
. Il s’étend au-delà des axes (mais pas au-delà de la figure, c’est-à-dire que la taille de la figure est pas ajustée automatiquement pour tracer tous vos artistes).
Les unités pour x, y et le rayon correspondent aux unités de données par défaut. Dans ce cas, je n'ai tracé aucun objet sur mes axes (fig.gca()
renvoie les axes actuels) et, comme les limites n'ont jamais été définies, leur valeur par défaut est x et y sont compris entre 0 et 1.
Voici une suite de l'exemple montrant comment les unités sont importantes:
circle1 = plt.Circle((0, 0), 2, color='r')
# now make a circle with no fill, which is good for hi-lighting key results
circle2 = plt.Circle((5, 5), 0.5, color='b', fill=False)
circle3 = plt.Circle((10, 10), 2, color='g', clip_on=False)
ax = plt.gca()
ax.cla() # clear things for fresh plot
# change default range so that new circles will work
ax.set_xlim((0, 10))
ax.set_ylim((0, 10))
# some data
ax.plot(range(11), 'o', color='black')
# key data point that we are encircling
ax.plot((5), (5), 'o', color='y')
ax.add_artist(circle1)
ax.add_artist(circle2)
ax.add_artist(circle3)
fig.savefig('plotcircles2.png')
qui se traduit par:
Vous pouvez voir comment je règle le remplissage du deuxième cercle sur False
, ce qui est utile pour encercler les résultats clés (comme mon point de données jaune).
import matplotlib.pyplot as plt
circle1=plt.Circle((0,0),.2,color='r')
plt.gcf().gca().add_artist(circle1)
Une version condensée rapide de la réponse acceptée, permettant de brancher rapidement un cercle dans un tracé existant. Reportez-vous à la réponse acceptée et aux autres réponses pour comprendre les détails.
Au fait:
gcf()
signifie obtenir le chiffre actuelgca()
signifie Obtenir l'axe actuelSi vous voulez tracer un ensemble de cercles, vous voudrez peut-être voir cet article ou cet article (un peu plus récent). La publication proposait une fonction nommée circles
.
La fonction circles
fonctionne comme scatter
, mais la taille des cercles tracés est exprimée en unité de données.
Voici un exemple:
from pylab import *
figure(figsize=(8,8))
ax=subplot(aspect='equal')
#plot one circle (the biggest one on bottom-right)
circles(1, 0, 0.5, 'r', alpha=0.2, lw=5, edgecolor='b', transform=ax.transAxes)
#plot a set of circles (circles in diagonal)
a=arange(11)
out = circles(a, a, a*0.2, c=a, alpha=0.5, edgecolor='none')
colorbar(out)
xlim(0,10)
ylim(0,10)
#!/usr/bin/python
import matplotlib.pyplot as plt
import numpy as np
def xy(r,phi):
return r*np.cos(phi), r*np.sin(phi)
fig = plt.figure()
ax = fig.add_subplot(111,aspect='equal')
phis=np.arange(0,6.28,0.01)
r =1.
ax.plot( *xy(r,phis), c='r',ls='-' )
plt.show()
Ou, si vous préférez, regardez le path
s, http://matplotlib.sourceforge.net/users/path_tutorial.html
Si vous souhaitez que le "cercle" conserve un ratio d'aspect visuel de 1, quelles que soient les coordonnées de données, vous pouvez utiliser la méthode scatter (). http://matplotlib.org/1.3.1/api/pyplot_api.html#matplotlib.pyplot.scatter
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [10, 20, 30, 40, 50]
r = [100, 80, 60, 40, 20] # in points, not data units
fig, ax = plt.subplots(1, 1)
ax.scatter(x, y, s=r)
fig.show()
Extension de la réponse acceptée pour un cas d'utilisation commun. En particulier:
Affichez les cercles à un rapport de format naturel.
Étendre automatiquement les limites des axes pour inclure les nouveaux cercles tracés.
Exemple autonome:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.add_patch(plt.Circle((0, 0), 0.2, color='r', alpha=0.5))
ax.add_patch(plt.Circle((1, 1), 0.5, color='#00ffff', alpha=0.5))
ax.add_artist(plt.Circle((1, 0), 0.5, color='#000033', alpha=0.5))
#Use adjustable='box-forced' to make the plot area square-shaped as well.
ax.set_aspect('equal', adjustable='datalim')
ax.plot() #Causes an autoscale update.
plt.show()
Notez la différence entre ax.add_patch(..)
et ax.add_artist(..)
: des deux, seul le first fait que les machines à mise à l'échelle automatique prennent en compte le cercle (référence: discussion ). Ainsi, après avoir exécuté le code ci-dessus, nous obtenons:
Voir aussi: set_aspect(..)
documentation .