Zeichnen Sie einen Kreis mit Pyplot

158

überraschenderweise fand ich keine einfache Beschreibung, wie man einen Kreis mit matplotlib.pyplot (bitte kein Pylab) als Eingabezentrum (x, y) und Radius r zeichnet. Ich habe einige Varianten davon ausprobiert:

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

... aber es hat immer noch nicht funktioniert.

Max Li
quelle
Ich bin mir sicher, dass dies möglich ist, aber matplotlib zielt hauptsächlich auf das Zeichnen ab (dh hier sind einige Daten, setzen Sie sie in ein Diagramm), nicht auf das Zeichnen, daher ist es möglicherweise nicht ganz einfach.
Thomas K
Der Radius von Streudiagrammpunkten wird zunehmend zur Visualisierung von Daten verwendet. Google Charts nennt sie "Bubble Plots". Gapminder.org ist ein gutes Beispiel. Dies ist Zeichnen, nicht Zeichnen. Ich habe das Matplotlib-Github-Repo vergeblich nach "Blase" und "Streuradius" durchsucht, daher glaube ich nicht, dass dies auf der To-Do-Liste steht, was das Hinzufügen einer Funktion betrifft.
Bennett Brown
1
plt.scatter () akzeptiert ein Größenargument. Sie können Listen für die x- und y-Koordinaten von Kreisen, die Radien der Kreise und die Farben der Kreise übergeben. matplotlib.org/1.3.1/api/… . Mein Fehler früher, als ich dachte, dass solche Funktionen nicht bereits in matplotlib enthalten waren.
Bennett Brown
3
Nur um zu erwähnen: plt.Circle(..)leitet an matplotlib.patches.Circle(). Eine Lösung ohne Pyplot wäre also circle = matplotlib.patches.Circle(..); axes.add_artist(circle).
ImportanceOfBeingErnest

Antworten:

203

Sie müssen es einer Achse hinzufügen. A Circleist eine Unterklasse von a Artistund a axeshat eine add_artistMethode.

Hier ist ein Beispiel dafür:

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

Daraus ergibt sich folgende Abbildung:

Der erste Kreis befindet sich am Ursprung, ist jedoch standardmäßig clip_onso True, dass der Kreis immer dann abgeschnitten wird, wenn er sich über den Kreis hinaus erstreckt axes. Der dritte (grüne) Kreis zeigt, was passiert, wenn Sie das nicht abschneiden Artist. Es erstreckt sich über die Achsen hinaus (aber nicht über die Figur hinaus, dh die Figurengröße wird nicht automatisch angepasst, um alle Ihre Künstler zu zeichnen).

Die Einheiten für x, y und Radius entsprechen standardmäßig Dateneinheiten. In diesem Fall habe ich nichts auf meinen Achsen gezeichnet ( fig.gca()gibt die aktuellen Achsen zurück), und da die Grenzwerte nie festgelegt wurden, wird standardmäßig ein x- und y-Bereich von 0 bis 1 verwendet.

Hier ist eine Fortsetzung des Beispiels, das zeigt, wie wichtig Einheiten sind:

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

was in ... endet:

Sie können sehen, wie ich die Füllung des 2. Kreises auf setze False, was nützlich ist, um wichtige Ergebnisse zu umkreisen (wie mein gelber Datenpunkt).

Yann
quelle
4
Ich mag diese Antwort, weil Sie einen Kreis "zeichnen", anstatt zu zeichnen. Obwohl das Planen auch mein erster Instinkt gewesen wäre.
Samb8s
7
Zu Ihrer Information: Es sieht so aus, als ob die Circle-Klasse von matplotlib.pyplot zu matplotlib.patches verschoben wurde, seit diese Antwort geschrieben wurde.
Pavon
6
Aber doch die Kreise sind oval!
Rubenvb
1
@rubenvb siehe meine andere Antwort: stackoverflow.com/questions/9230389/…
Yann
3
@pavon Für mich matplotlib.pyplot.Circle == matplotlib.patches.Circleausgewertet True, also sind sie wahrscheinlich Aliase.
Evgeni Sergeev
66
import matplotlib.pyplot as plt
circle1=plt.Circle((0,0),.2,color='r')
plt.gcf().gca().add_artist(circle1)

Eine schnell komprimierte Version der akzeptierten Antwort, um schnell einen Kreis in ein vorhandenes Diagramm einzufügen. Beziehen Sie sich auf die akzeptierte Antwort und andere Antworten, um die Details zu verstehen.

Apropos:

  • gcf() bedeutet Aktuelle Zahl abrufen
  • gca() bedeutet Aktuelle Achse abrufen
jmn
quelle
4
Perfekt! genau das, was ich gerade sehen musste. Ihr 'Übrigens' war auch sehr hilfreich! dir(fig)zeigt mir über 30 'get'-Methoden, hat aber gcakeinen get_current_axisAlias. Diese Art von Fyi-Antworten ist wunderbar.
Uhoh
6
Sie können tatsächlich tun, plt.gca()anstattplt.gcf().gca()
Andre Holzner
38

Wenn Sie eine Reihe von Kreisen zeichnen möchten, möchten Sie möglicherweise diesen Beitrag oder diesen Kern (etwas neuer) sehen. Der Beitrag bot eine Funktion namens circles.

Die Funktion circlesfunktioniert wie scatter, aber die Größe der gezeichneten Kreise ist in Dateneinheit angegeben.

Hier ist ein Beispiel:

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)

Geben Sie hier die Bildbeschreibung ein

Syrtis Major
quelle
Was macht transform=ax.transAxesdas
Lee
3
@Lee Das ist für den Kreis in der rechten unteren Ecke. Transformieren Sie die Daten in Achsenkoordinaten, dh (1,1) bedeutet rechte obere Ecke in Achsen, (1,0) bedeutet rechte untere Ecke usw.
Syrtis Major
4
Dies sollte ein Teil von matplotlib sein.
JustAC0der
Kann dies mit verwendet werden mplleaflet? Wenn ja, können Sie bitte ein Beispiel nennen?
François M.
@fmalaussena Da dieses Code-Snippet rein ist matplotlib, sollte es kompatibel sein, mplleafletobwohl ich es nie ausprobiert habe.
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()

Oder, wenn Sie es vorziehen, schauen Sie sich die paths an, http://matplotlib.sourceforge.net/users/path_tutorial.html

ev-br
quelle
2
Trignometrische Gleichung eines Kreises und Degress 0 bis 360, was 0 bis 6,28319 Bogenmaß entspricht mathopenref.com/coordparamcircle.html
Alex Punnen
19

Wenn Sie möchten, dass der "Kreis" unabhängig von den Datenkoordinaten ein visuelles Seitenverhältnis von 1 beibehält, können Sie die Scatter () -Methode verwenden. 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()

Das Bild ist ein Streudiagramm.  Fünf Kreise entlang der Linie y = 10x haben abnehmende Radien von links unten nach rechts oben.  Obwohl der Graph quadratisch ist, hat die y-Achse den 10-fachen Bereich der x-Achse.  Trotzdem beträgt das Seitenverhältnis der Kreise 1 auf dem Bildschirm.

Bennett Brown
quelle
11

Erweiterung der akzeptierten Antwort für einen allgemeinen Anwendungsfall. Bestimmtes:

  1. Zeigen Sie die Kreise in einem natürlichen Seitenverhältnis an.

  2. Erweitern Sie die Achsengrenzen automatisch um die neu gezeichneten Kreise.

In sich geschlossenes Beispiel:

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

Beachten Sie den Unterschied zwischen ax.add_patch(..)und ax.add_artist(..): von beiden: Nur bei ersteren werden Autoscaling-Maschinen den Kreis berücksichtigen (Referenz: Diskussion ). Nach dem Ausführen des obigen Codes erhalten wir also:

add_patch (..) vs add_artist (..)

Siehe auch: set_aspect(..)Dokumentation .

Evgeni Sergeev
quelle
In Python3 müssen Sie herausnehmen, fig, ax = plt.subplots()sonst erhalten Sie zwei Fenster (eines ist leer).
albus_c
1

Ich sehe Diagramme mit der Verwendung von (.circle), aber basierend auf dem, was Sie vielleicht tun möchten, können Sie dies auch ausprobieren:

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)

Einfaches konzentrisches Kreisdiagramm mit linearen Fortschrittspunkten

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

Eingekreiste Punkte eines Klassifizierungsproblems.

Inyang Kpongette
quelle
0

Hallo, ich habe einen Code zum Zeichnen eines Kreises geschrieben. Es hilft beim Zeichnen aller Arten von Kreisen. Das Bild zeigt den Kreis mit Radius 1 und Mittelpunkt bei 0,0 Der Mittelpunkt und der Radius können beliebig bearbeitet werden.

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

Viel Glück

AJEET
quelle
0

Ähnlich wie beim Streudiagramm können Sie auch ein normales Diagramm mit Kreislinienstil verwenden. Mit den markersizeParametern können Sie den Radius eines Kreises einstellen:

import matplotlib.pyplot as plt

plt.plot(200, 2, 'o', markersize=7)
Marcin Szałajski
quelle