web-dev-qa-db-fra.com

tracer un cercle avec pyplot

é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.

130
Max Li

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).

166
Yann
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 actuel
  • gca() signifie Obtenir l'axe actuel
51
jmn

Si 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)

enter image description here

36
Syrtis Major
#!/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 paths, http://matplotlib.sourceforge.net/users/path_tutorial.html

19
ev-br

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()

Image is a scatter plot. Five circles along the line y=10x have decreasing radii from bottom left to top right. Although the graph is square-shaped, the y-axis has 10 times the range of the x-axis. Even so, the aspect ratio of the circles is 1 on the screen.

19
Bennett Brown

Extension de la réponse acceptée pour un cas d'utilisation commun. En particulier:

  1. Affichez les cercles à un rapport de format naturel.

  2. É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:

add_patch(..) vs add_artist(..)

Voir aussi: set_aspect(..) documentation .

7
Evgeni Sergeev