trazar un círculo con pyplot


158

Sorprendentemente, no encontré una descripción directa sobre cómo dibujar un círculo con matplotlib.pyplot (por favor, sin pylab) tomando como centro de entrada (x, y) y radio r. Intenté algunas variantes de esto:

import matplotlib.pyplot as plt
circle=plt.Circle((0,0),2)
# here must be something like circle.plot() or not?
plt.show()

... pero aún así no funcionó.


Estoy seguro de que es posible hacer esto, pero matplotlib está dirigido principalmente a trazar (es decir, aquí hay algunos datos, ponerlos en un gráfico), no dibujar, por lo que podría no ser del todo sencillo.
Thomas K

El radio de los puntos del diagrama de dispersión se usa cada vez más para visualizar datos. Los gráficos de Google los llaman "gráficos de burbujas". Gapminder.org es un buen ejemplo. Esto es trazar, no dibujar. Busqué en el repositorio matplotlib github "burbuja" y "radio de dispersión" en vano, así que no creo que esto esté en la lista de tareas pendientes en cuanto a agregar una función.
Bennett Brown,

1
plt.scatter () toma un argumento de tamaño. Puede pasar listas para las coordenadas x e y de los círculos, los radios de los círculos y los colores de los círculos. matplotlib.org/1.3.1/api/… . Mi error anterior, al pensar que dicha funcionalidad aún no estaba en matplotlib.
Bennett Brown,

3
Solo por mencionar: plt.Circle(..)dirige a matplotlib.patches.Circle(). Entonces, una solución sin pyplot sería circle = matplotlib.patches.Circle(..); axes.add_artist(circle).
ImportanceOfBeingErnest

Respuestas:


203

Necesita agregarlo a los ejes. A Circlees una subclase de an Artist, y an axestiene un add_artistmétodo.

Aquí hay un ejemplo de hacer esto:

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

Esto da como resultado la siguiente figura:

El primer círculo está en el origen, pero por defecto lo clip_onestá True, por lo que el círculo se recorta cuando se extiende más allá del axes. El tercer círculo (verde) muestra lo que sucede cuando no recorta el Artist. Se extiende más allá de los ejes (pero no más allá de la figura, es decir, el tamaño de la figura no se ajusta automáticamente para representar a todos sus artistas).

Las unidades para x, y y radio corresponden a unidades de datos por defecto. En este caso, no tracé nada en mis hachas (fig.gca() devuelve los ejes actuales), y dado que los límites nunca se han establecido, el valor predeterminado es un rango x e y de 0 a 1.

Aquí hay una continuación del ejemplo, que muestra cómo importan las unidades:

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

lo que resulta en:

Puede ver cómo configuro el relleno del segundo círculo False, lo cual es útil para rodear los resultados clave (como mi punto de datos amarillo).


44
Me gusta esta respuesta porque estás "dibujando" un círculo, en lugar de trazar. Aunque tramar habría sido mi primer instinto también
samb8s

77
FYI: Parece que la clase Circle se ha movido de matplotlib.pyplot a matplotlib.patches desde que se escribió esta respuesta.
Pavón

66
¡Pero pero pero los círculos son ovales!
rubenvb

1
@rubenvb vea mi otra respuesta: stackoverflow.com/questions/9230389/…
Yann

3
@pavon Para mí se matplotlib.pyplot.Circle == matplotlib.patches.Circleevalúa True, por lo que probablemente sean alias.
Evgeni Sergeev

66
import matplotlib.pyplot as plt
circle1=plt.Circle((0,0),.2,color='r')
plt.gcf().gca().add_artist(circle1)

Una versión condensada rápida de la respuesta aceptada, para conectar rápidamente un círculo en una trama existente. Consulte la respuesta aceptada y otras respuestas para comprender los detalles.

Por cierto:

  • gcf() significa Obtener figura actual
  • gca() significa Obtener eje actual

44
¡Perfecto! exactamente lo que necesitaba ver en este momento. ¡Tu 'Por cierto' también fue muy útil! dir(fig)me muestra más de 30 métodos 'get', pero gcano tiene un get_current_axisalias. Este tipo de respuestas para tu información son maravillosas.
uhoh

66
en realidad puedes hacer en plt.gca()lugar deplt.gcf().gca()
Andre Holzner

38

Si desea trazar un conjunto de círculos, es posible que desee ver esta publicación o esta esencia (un poco más nueva). La publicación ofrecía una función llamada circles.

La función circlesfunciona como scatter, pero los tamaños de los círculos trazados están en la unidad de datos.

Aquí hay un ejemplo:

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)

ingrese la descripción de la imagen aquí


¿Qué transform=ax.transAxeshacer?
Lee

3
@Lee Eso es para el círculo en la esquina inferior derecha, transforma los datos en coordenadas de ejes, es decir (1,1) significa esquina superior derecha en ejes, (1,0) significa esquina inferior derecha, etc.
Syrtis Major

44
Esto debería ser parte de matplotlib.
JustAC0der

¿Se puede usar esto con mplleaflet? Si es así, ¿podría dar un ejemplo, por favor?
François M.

@fmalaussena Como este fragmento de código es puro matplotlib, supongo que debería ser compatible, mplleafletaunque nunca lo intenté.
Syrtis Major

21
#!/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()

O, si lo prefiere, mire paths, http://matplotlib.sourceforge.net/users/path_tutorial.html


2
Ecuación trignométrica de un círculo y degresión 0 tp 360, que se traduce de 0 a 6.28319 radianes mathopenref.com/coordparamcircle.html
Alex Punnen


11

Extender la respuesta aceptada para un caso de uso común. En particular:

  1. Ver los círculos en una relación de aspecto natural.

  2. Extienda automáticamente los límites de los ejes para incluir los círculos recién trazados.

Ejemplo autónomo:

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

Tenga en cuenta la diferencia entre ax.add_patch(..)y ax.add_artist(..): de los dos, solo el primero hace que la maquinaria de autoescalado tenga en cuenta el círculo (referencia: discusión ), por lo que después de ejecutar el código anterior obtenemos:

add_patch (..) vs add_artist (..)

Ver también: set_aspect(..)documentación .


En python3, debe sacar fig, ax = plt.subplots(), de lo contrario obtendrá dos ventanas (una está en blanco).
albus_c

1

Veo tramas con el uso de (.circle) pero en función de lo que quieras hacer, también puedes probar esto:

import matplotlib.pyplot as plt
import numpy as np

x = list(range(1,6))
y = list(range(10, 20, 2))

print(x, y)

for i, data in enumerate(zip(x,y)):
    j, k = data
    plt.scatter(j,k, marker = "o", s = ((i+1)**4)*50, alpha = 0.3)

Diagrama de círculo concéntrico simple usando puntos de progreso lineales

centers = np.array([[5,18], [3,14], [7,6]])
m, n = make_blobs(n_samples=20, centers=[[5,18], [3,14], [7,6]], n_features=2, 
cluster_std = 0.4)
colors = ['g', 'b', 'r', 'm']

plt.figure(num=None, figsize=(7,6), facecolor='w', edgecolor='k')
plt.scatter(m[:,0], m[:,1])

for i in range(len(centers)):

    plt.scatter(centers[i,0], centers[i,1], color = colors[i], marker = 'o', s = 13000, alpha = 0.2)
    plt.scatter(centers[i,0], centers[i,1], color = 'k', marker = 'x', s = 50)

plt.savefig('plot.png')

Puntos en un círculo de un problema de clasificación.


0

Hola, he escrito un código para dibujar un círculo. Ayudará a dibujar todo tipo de círculos. La imagen muestra el círculo con radio 1 y centro en 0,0 El centro y el radio se pueden editar de cualquier elección.

## Draw a circle with center and radius defined
## Also enable the coordinate axes
import matplotlib.pyplot as plt
import numpy as np
# Define limits of coordinate system
x1 = -1.5
x2 = 1.5
y1 = -1.5
y2 = 1.5

circle1 = plt.Circle((0,0),1, color = 'k', fill = False, clip_on = False)
fig, ax = plt.subplots()
ax.add_artist(circle1)
plt.axis("equal")
ax.spines['left'].set_position('zero')
ax.spines['bottom'].set_position('zero')
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.yaxis.set_ticks_position('left')
plt.xlim(left=x1)
plt.xlim(right=x2)
plt.ylim(bottom=y1)
plt.ylim(top=y2)
plt.axhline(linewidth=2, color='k')
plt.axvline(linewidth=2, color='k')

##plt.grid(True)
plt.grid(color='k', linestyle='-.', linewidth=0.5)
plt.show()

Buena suerte


0

De manera similar al diagrama de dispersión, también puede usar el diagrama normal con estilo de línea circular. Usando el markersizeparámetro puede ajustar el radio de un círculo:

import matplotlib.pyplot as plt

plt.plot(200, 2, 'o', markersize=7)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.