narysuj okrąg z pyplotem

158

zaskakująco nie znalazłem prostego opisu, jak narysować okrąg z matplotlib.pyplot (proszę nie pylab) przyjmując jako środek wprowadzania (x, y) i promień r. Wypróbowałem kilka wariantów tego:

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

... ale nadal nie działało.

Max Li
źródło
Jestem pewien, że jest to możliwe, ale matplotlib jest nastawiony głównie na kreślenie (tj. Tutaj są dane, umieść je na wykresie), a nie na rysowanie, więc może to nie być całkowicie proste.
Thomas K
Do wizualizacji danych coraz częściej wykorzystuje się promień punktów wykresu rozrzutu. Wykresy Google nazywają je „wykresami bąbelkowymi”. Gapminder.org to dobry przykład. To jest spisek, nie rysunek. Przeszukałem repozytorium github matplotlib pod kątem „bubble” i „scatter radius” bezskutecznie, więc nie sądzę, aby to było na liście rzeczy do zrobienia, jeśli chodzi o dodanie funkcji.
Bennett Brown
1
plt.scatter () przyjmuje argument rozmiaru. Możesz przekazać listy współrzędnych x i y okręgów, ich promieni i kolorów okręgów. matplotlib.org/1.3.1/api/… . Mój błąd wcześniej, myśląc, że takiej funkcjonalności nie ma już w matplotlib.
Bennett Brown
3
Wystarczy wspomnieć: plt.Circle(..)kieruje do matplotlib.patches.Circle(). Więc rozwiązanie bez pyplota byłoby circle = matplotlib.patches.Circle(..); axes.add_artist(circle).
ImportanceOfBeingErnest

Odpowiedzi:

203

Musisz dodać go do osi. A Circlejest podklasą klasy an Artist, a an axesma add_artistmetodę.

Oto przykład, jak to zrobić:

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

Z tego wynika następujący rysunek:

Pierwszy okrąg znajduje się w punkcie początkowym, ale domyślnie tak clip_onjest True, więc okrąg jest przycinany, gdy kiedykolwiek wychodzi poza axes. Trzecie (zielone) kółko pokazuje, co się stanie, gdy nie przypniesz pliku Artist. Rozciąga się poza osie (ale nie poza figurę, tj. Rozmiar figury nie jest automatycznie dostosowywany do kreślenia wszystkich twoich artystów).

Jednostki x, y i promień domyślnie odpowiadają jednostkom danych. W tym przypadku nie wykreśliłem niczego na moich osiach ( fig.gca()zwraca bieżące osie), a ponieważ limity nigdy nie zostały ustawione, domyślnie są one w zakresie xiy od 0 do 1.

Oto kontynuacja przykładu, pokazująca znaczenie jednostek:

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

Co skutkuje w:

Możesz zobaczyć, jak ustawiłem wypełnienie drugiego koła na False, co jest przydatne do otaczania kluczowych wyników (takich jak mój żółty punkt danych).

Yann
źródło
4
Podoba mi się ta odpowiedź, ponieważ „rysujesz” okrąg, zamiast kreślić. Chociaż knucie też byłoby moim pierwszym odruchem.
samb8s
7
FYI: Wygląda na to, że klasa Circle została przeniesiona z matplotlib.pyplot do matplotlib.patches od czasu napisania tej odpowiedzi.
pavon
6
Ale ale koła są owalne!
rubenvb
1
@rubenvb zobacz moją drugą odpowiedź: stackoverflow.com/questions/9230389/…
Yann
3
@pavon Dla mnie matplotlib.pyplot.Circle == matplotlib.patches.Circleocenia się na True, więc prawdopodobnie są to aliasy.
Evgeni Sergeev
66
import matplotlib.pyplot as plt
circle1=plt.Circle((0,0),.2,color='r')
plt.gcf().gca().add_artist(circle1)

Szybka, skondensowana wersja zaakceptowanej odpowiedzi, aby szybko podłączyć okrąg do istniejącej fabuły. Zapoznaj się z zaakceptowaną odpowiedzią i innymi odpowiedziami, aby zrozumieć szczegóły.

Tak poza tym:

  • gcf() oznacza Pobierz bieżącą figurę
  • gca() oznacza Pobierz bieżącą oś
jmn
źródło
4
Idealny! dokładnie to, co chciałem zobaczyć w tej chwili. Twoje „Przy okazji” też było całkiem pomocne! dir(fig)pokazuje mi ponad 30 metod „get”, ale gcanie ma get_current_axisaliasu. Tego rodzaju odpowiedzi fyi są cudowne.
uhoh
6
możesz zrobić plt.gca()zamiastplt.gcf().gca()
Andre Holzner
38

Jeśli chcesz narysować zestaw kręgów, możesz chcieć zobaczyć ten post lub ten tekst (nieco nowszy). Post oferował funkcję o nazwie circles.

Funkcja circlesdziała podobnie scatter, ale rozmiary kreślonych okręgów są w jednostce danych.

Oto przykład:

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)

wprowadź opis obrazu tutaj

Syrtis Major
źródło
Co robi transform=ax.transAxes?
Lee
3
@Lee To dla okręgu w prawym dolnym rogu, przekształć dane we współrzędne osi, tj. (1,1) oznacza prawy górny róg na osiach, (1,0) oznacza prawy dolny róg itd.
Syrtis Major
4
To powinno być częścią matplotlib.
JustAC0der
Czy można tego używać z mplleaflet? Jeśli tak, czy mógłbyś podać przykład?
François M.
@fmalaussena Ponieważ ten fragment kodu jest czysty matplotlib, myślę, że powinien być zgodny z, mplleafletchociaż nigdy nie próbowałem.
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()

Lub, jeśli wolisz, spójrz na paths, http://matplotlib.sourceforge.net/users/path_tutorial.html

ev-br
źródło
2
Trignometryczne równanie okręgu i degress 0 tp 360, co przekłada się na 0 do 6,28319 radianów mathopenref.com/coordparamcircle.html
Alex Punnen
19

Jeśli chcesz, aby „koło” zachowywało wizualny współczynnik proporcji 1 bez względu na współrzędne danych, możesz użyć metody 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()

Obraz jest wykresem punktowym.  Pięć okręgów wzdłuż linii y = 10x ma zmniejszające się promienie od lewej dolnej do prawej górnej.  Chociaż wykres ma kształt kwadratu, oś Y ma 10-krotny zakres od osi X.  Mimo to proporcje kół na ekranie wynoszą 1.

Bennett Brown
źródło
11

Rozszerzenie zaakceptowanej odpowiedzi na typowy przypadek użycia. W szczególności:

  1. Oglądaj okręgi w naturalnych proporcjach.

  2. Automatycznie wydłuż granice osi, aby uwzględnić nowo wykreślone okręgi.

Samodzielny przykład:

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

Zwróć uwagę na różnicę między ax.add_patch(..)i ax.add_artist(..): z tych dwóch, tylko pierwszy powoduje, że mechanizm autoskalowania bierze pod uwagę koło (odniesienie: dyskusja ), więc po uruchomieniu powyższego kodu otrzymujemy:

add_patch (..) vs add_artist (..)

Zobacz też: set_aspect(..)dokumentacja .

Evgeni Sergeev
źródło
W python3 musisz wyjąć fig, ax = plt.subplots(), w przeciwnym razie otrzymasz dwa okna (jedno jest puste).
albus_c
1

Widzę wykresy z użyciem (.circle), ale w oparciu o to, co możesz chcieć zrobić, możesz również wypróbować to:

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)

Prosty koncentryczny wykres kołowy z liniowymi punktami progresji

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

Zakreślone punkty problemu klasyfikacyjnego.

inyang kpongette
źródło
0

Witam napisałem kod do rysowania koła. Pomoże w rysowaniu wszelkiego rodzaju okręgów. Obraz przedstawia okrąg o promieniu 1 i środku w 0,0 . Środek i promień można dowolnie edytować.

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

Powodzenia

AJEET
źródło
0

Podobnie jak w przypadku wykresu punktowego, można również użyć normalnego wykresu ze stylem linii koła. Za pomocą markersizeparametru można dopasować promień okręgu:

import matplotlib.pyplot as plt

plt.plot(200, 2, 'o', markersize=7)
Marcin Szałajski
źródło