traccia un cerchio con pyplot


158

sorprendentemente non ho trovato una descrizione semplice su come disegnare un cerchio con matplotlib.pyplot (per favore, no pylab) prendendo come centro di input (x, y) e raggio r. Ho provato alcune varianti di questo:

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

... ma ancora non ha funzionato.


Sono sicuro che è possibile farlo, ma matplotlib è principalmente finalizzato alla stampa (cioè qui ci sono alcuni dati, mettili in un grafico), non disegnando, quindi potrebbe non essere del tutto semplice.
Thomas K,

Il raggio dei punti scatterplot viene sempre più utilizzato per visualizzare i dati. I grafici di Google li chiamano "grafici a bolle". Gapminder.org è un buon esempio. Questo è un complotto, non un disegno. Ho cercato inutilmente il repository github matplotlib per "bolla" e "raggio di dispersione", quindi non credo che questo sia nell'elenco delle cose da fare per quanto riguarda l'aggiunta di una funzione.
Bennett Brown,

1
plt.scatter () accetta un argomento size. Puoi passare elenchi per le coordinate X e Y dei cerchi, i raggi dei cerchi e i colori dei cerchi. matplotlib.org/1.3.1/api/… . Il mio errore prima, nel pensare che tale funzionalità non era già in matplotlib.
Bennett Brown,

3
Solo per citare: plt.Circle(..)dirige a matplotlib.patches.Circle(). Quindi sarebbe una soluzione senza pyplot circle = matplotlib.patches.Circle(..); axes.add_artist(circle).
ImportanceOfBeingErnest

Risposte:


203

Devi aggiungerlo a un asse. A Circleè una sottoclasse di an Artiste an axesha un add_artistmetodo.

Ecco un esempio di ciò:

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

Ciò si traduce nella seguente figura:

Il primo cerchio è all'origine, ma per impostazione predefinita lo clip_onè True, quindi il cerchio viene ritagliato ogni volta che si estende oltre il axes. Il terzo cerchio (verde) mostra cosa succede quando non ritagli Artist. Si estende oltre gli assi (ma non oltre la figura, ovvero la dimensione della figura non viene regolata automaticamente per tracciare tutti i tuoi artisti).

Le unità per x, y e raggio corrispondono alle unità dati per impostazione predefinita. In questo caso, non ho tracciato nulla sui miei assi ( fig.gca()restituisce gli assi correnti) e poiché i limiti non sono mai stati impostati, per impostazione predefinita hanno un intervallo xey da 0 a 1.

Ecco una continuazione dell'esempio, che mostra come le unità contano:

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

che si traduce in:

Puoi vedere come ho impostato il riempimento del 2 ° cerchio su False, che è utile per circondare i risultati chiave (come il mio punto dati giallo).


4
Mi piace questa risposta perché stai "disegnando" un cerchio, piuttosto che complottare. Anche se la trama sarebbe stato anche il mio primo istinto.
samb8s,

7
Cordiali saluti: Sembra che la classe Circle sia passata da matplotlib.pyplot a matplotlib.patches da quando è stata scritta questa risposta.
pavon,

6
Ma ma i cerchi sono ovali!
rubenvb,

1
@rubenvb vedi la mia altra risposta: stackoverflow.com/questions/9230389/…
Yann

3
@pavon Per me matplotlib.pyplot.Circle == matplotlib.patches.Circlevaluta True, quindi sono probabilmente alias.
Evgeni Sergeev,

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

Una versione ridotta della risposta accettata, per collegare rapidamente un cerchio a un diagramma esistente. Fare riferimento alla risposta accettata e ad altre risposte per comprendere i dettagli.

A proposito:

  • gcf() significa Ottieni la figura corrente
  • gca() significa Ottieni asse corrente

4
Perfetto! proprio quello che dovevo vedere adesso. Anche il tuo 'A proposito' mi è stato di grande aiuto! dir(fig)mi mostra oltre 30 metodi "get", ma gcanon ha get_current_axisalias. Questi tipi di risposte sono meravigliose.
uho,

6
si può effettivamente fare plt.gca()invece diplt.gcf().gca()
Andre Holzner

38

Se vuoi tracciare una serie di cerchi, potresti voler vedere questo post o questa sintesi (un po 'più recente). Il post offriva una funzione denominata circles.

La funzione circlesfunziona come scatter, ma le dimensioni dei cerchi tracciati sono in unità dati.

Ecco un esempio:

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)

inserisci qui la descrizione dell'immagine


Cosa fa transform=ax.transAxes?
Lee,

3
@Lee Questo è per il cerchio nell'angolo inferiore destro, trasforma i dati in coordinate degli assi, ovvero (1,1) significa angolo superiore destro negli assi, (1,0) significa angolo inferiore destro, ecc.
Syrtis Major

4
Questo dovrebbe far parte di matplotlib.
JustAC0der

Questo può essere usato con mplleaflet? In tal caso, potresti fornire un esempio, per favore?
François M.,

@fmalaussena Poiché questo frammento di codice è puro matplotlib, immagino che dovrebbe essere compatibile mplleafletanche se non l'ho mai provato.
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()

Oppure, se preferisci, guarda la pathpagina http://matplotlib.sourceforge.net/users/path_tutorial.html


2
Equazione trignometrica di un cerchio e degress 0 tp 360, che si traduce da 0 a 6.28319 radianti mathopenref.com/coordparamcircle.html
Alex Punnen


11

Estensione della risposta accettata per un caso d'uso comune. In particolare:

  1. Visualizza i cerchi con proporzioni naturali.

  2. Estendi automaticamente i limiti degli assi per includere i cerchi appena tracciati.

Esempio autonomo:

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

Nota la differenza tra ax.add_patch(..)e ax.add_artist(..): dei due, solo il primo fa in modo che il macchinario di scalabilità automatica tenga conto del cerchio (riferimento: discussione ), quindi dopo aver eseguito il codice sopra otteniamo:

add_patch (..) vs add_artist (..)

Vedi anche: set_aspect(..)documentazione .


In python3, devi eliminarlo fig, ax = plt.subplots(), altrimenti otterrai due finestre (una è vuota).
albus_c,

1

Vedo grafici con l'uso di (.circle) ma in base a ciò che potresti voler fare puoi anche provare questo:

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)

Grafico a cerchi concentrici semplici con punti di avanzamento lineari

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

Punti cerchiati di un problema di classificazione.


0

Ciao, ho scritto un codice per disegnare un cerchio. Aiuterà a disegnare tutti i tipi di cerchi. L'immagine mostra il cerchio con raggio 1 e centro a 0,0 Il centro e il raggio possono essere modificati di qualsiasi scelta.

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

In bocca al lupo


0

Analogamente al grafico a dispersione, puoi anche utilizzare il diagramma normale con lo stile della linea circolare. Utilizzando il markersizeparametro è possibile regolare il raggio di un cerchio:

import matplotlib.pyplot as plt

plt.plot(200, 2, 'o', markersize=7)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.