построить круг с pyplot

158

Удивительно, но я не нашел прямого описания того, как нарисовать круг с помощью matplotlib.pyplot (пожалуйста, без pylab), в качестве центра ввода (x, y) и радиуса r. Я попробовал несколько вариантов этого:

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

... но до сих пор не получилось.

Макс Ли
источник
Я уверен, что это возможно, но matplotlib нацелен главным образом на построение графиков (т.е. вот некоторые данные, разместите их на графике), а не на рисовании, так что это может быть не совсем просто.
Томас К
Радиус точек рассеяния все чаще используется для визуализации данных. Гугл чарты называют их «пузырьковыми диаграммами». Gapminder.org - хороший пример. Это является построение, а не рисовать. Я искал репозиторий matplotlib github для «пузыря» и «радиуса рассеяния», но безрезультатно, поэтому я не думаю, что это есть в списке дел, если добавить функцию.
Беннет Браун
1
plt.scatter () принимает аргумент размера. Вы можете передавать списки для x- и y-координат окружностей, радиусов окружностей и цветов окружностей. matplotlib.org/1.3.1/api/… . Моя ошибка ранее, при мысли, что такого функционала еще не было в matplotlib.
Беннетт Браун
3
Просто чтобы упомянуть: plt.Circle(..)направляет к matplotlib.patches.Circle(). Таким образом, решение без pyplot будет circle = matplotlib.patches.Circle(..); axes.add_artist(circle).
Важное значение

Ответы:

203

Вы должны добавить его к осям. A Circleявляется подклассом класса an Artist, и метод axesимеет add_artistметод.

Вот пример этого:

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

Это приводит к следующему рисунку:

Первый круг находится в начале координат, но по умолчанию clip_onэто Trueтак, поэтому круг обрезается, когда он выходит за пределы axes. Третий (зеленый) круг показывает, что происходит, когда вы не обрезаете Artist. Он простирается за пределы осей (но не за пределы фигуры, т. Е. Размер фигуры не регулируется автоматически для построения графика всех ваших художников).

Единицы для x, y и радиуса соответствуют единицам данных по умолчанию. В этом случае я ничего не рисовал на своих осях ( fig.gca()возвращает текущие оси), и, так как ограничения никогда не устанавливались, по умолчанию они находятся в диапазоне от x до y от 0 до 1.

Вот продолжение примера, показывающее, как важны единицы измерения:

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

что приводит к:

Вы можете видеть, как я установил заливку 2-го круга False, что полезно для обобщения ключевых результатов (например, моей желтой точки данных).

Yann
источник
4
Мне нравится этот ответ, потому что вы рисуете круг, а не чертите. Хотя заговор был бы и моим первым инстинктом.
samb8s
7
К вашему сведению: класс Circle с момента написания этого ответа переместился из matplotlib.pyplot в matplotlib.patches.
павон
6
Но, но, но круги овальные!
rubenvb
1
@rubenvb см. мой другой ответ: stackoverflow.com/questions/9230389/…
Янн
3
@pavon Для меня matplotlib.pyplot.Circle == matplotlib.patches.Circleоценивает True, так что они, вероятно, псевдонимы.
Евгений Сергеев
66
import matplotlib.pyplot as plt
circle1=plt.Circle((0,0),.2,color='r')
plt.gcf().gca().add_artist(circle1)

Быстрый сокращенный вариант принятого ответа, чтобы быстро вставить кружок в существующий сюжет. Обратитесь к принятому ответу и другим ответам, чтобы понять детали.

Кстати:

  • gcf() значит получить текущий рисунок
  • gca() значит получить текущую ось
jmn
источник
4
Отлично! именно то, что мне нужно было увидеть прямо сейчас. Ваше «Кстати» тоже было очень полезно! dir(fig)показывает более 30 методов get, но gcaне имеет get_current_axisпсевдонима. Такого рода ответы на вопросы фии замечательны.
ухо
6
Вы действительно можете сделать plt.gca()вместоplt.gcf().gca()
Андре Хольцнер
38

Если вы хотите построить набор кругов, вы можете захотеть увидеть этот пост или эту суть (немного новее). В посте предложена функция с именем circles.

Функция circlesработает аналогично scatter, но размеры нанесенных кругов указаны в единицах данных.

Вот пример:

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)

введите описание изображения здесь

Syrtis Major
источник
Что делает transform=ax.transAxes?
Ли
3
@Lee Это для круга в правом нижнем углу, преобразуйте данные в координаты осей, т.е. (1,1) означает правый верхний угол в осях, (1,0) означает правый нижний угол и т. Д.
Syrtis Major
4
Это должно быть частью matplotlib.
JustAC0der
Можно ли это использовать mplleaflet? Если да, не могли бы вы привести пример?
Франсуа М.
@fmalaussena Поскольку этот фрагмент кода является чистым matplotlib, я думаю, что он должен быть совместим с, mplleafletхотя я никогда не пробовал.
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()

Или, если хотите, посмотрите на pathстраницу http://matplotlib.sourceforge.net/users/path_tutorial.html.

эв-уш
источник
2
Тригонометрическое уравнение окружности и разности 0 tp 360, которое переводит от 0 до 6,28319 радиан mathopenref.com/coordparamcircle.html
Алекс Пуннен
19

Если вы хотите, чтобы «круг» поддерживал визуальное соотношение сторон 1 независимо от координат данных, вы можете использовать метод 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()

Изображение представляет собой точечный график.  Пять кругов вдоль линии y = 10x имеют уменьшающиеся радиусы снизу слева вверху справа.  Хотя график имеет квадратную форму, ось у имеет в 10 раз больший диапазон оси х.  Тем не менее, соотношение сторон кругов составляет 1 на экране.

Беннет Браун
источник
11

Расширение принятого ответа для общего использования. В частности:

  1. Просмотр кругов в естественном соотношении сторон.

  2. Автоматически расширяет пределы осей, чтобы включить вновь построенные круги.

Автономный пример:

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

Обратите внимание на разницу между ax.add_patch(..)и ax.add_artist(..): из двух, только первое заставляет автоматическое масштабирование принимать во внимание круг (ссылка: обсуждение ), поэтому после запуска приведенного выше кода мы получим:

add_patch (..) против add_artist (..)

Смотрите также: set_aspect(..)документация .

Евгений Сергеев
источник
В python3 вам нужно вынуть fig, ax = plt.subplots(), иначе вы получите два окна (одно пустое).
albus_c
1

Я вижу графики с использованием (.circle), но, основываясь на том, что вы хотите сделать, вы также можете попробовать это:

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)

Простая концентрическая окружность с использованием линейных прогрессирующих точек

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

Обведенные кружочками задачи классификации.

Иньянг Кпонгетте
источник
0

Здравствуйте, я написал код для рисования круга. Это поможет для рисования всех видов кругов. На рисунке показан круг с радиусом 1 и центром в 0,0 . Центр и радиус можно редактировать на любой выбор.

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

Удачи

Ajeet
источник
0

Аналогично точечной диаграмме вы также можете использовать нормальный график со стилем окружности. Используя markersizeпараметр, вы можете настроить радиус круга:

import matplotlib.pyplot as plt

plt.plot(200, 2, 'o', markersize=7)
Марцин Шалайски
источник