Заговорить круг с пипотом

На удивление, я не нашел прямолинейного описания того, как рисовать круг с помощью 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()

... но все равно не работал.

Ответ 1

Вам нужно добавить его к осям. A Circle является подклассом 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')

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

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

Ответ 2

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

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

Кстати:

  • gcf() означает "Получить текущий рисунок"
  • gca() означает "Получить текущую ось".

Ответ 3

Если вы хотите построить набор кругов, вы можете просмотреть этот пост или этот список(немного новее). В сообщении была предложена функция с именем 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)

enter image description here

Ответ 4

#!/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 s, http://matplotlib.sourceforge.net/users/path_tutorial.html

Ответ 5

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

Image is a scatter plot. Five circles along the line y=10x have decreasing radii from bottom left to top right. Although the graph is square-shaped, the y-axis has 10 times the range of the x-axis. Even so, the aspect ratio of the circles is 1 on the screen.

Ответ 6

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

  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(..) vs add_artist(..)

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

Ответ 7

Здравствуйте, я написал код для рисования круга. Это поможет для рисования всех видов кругов. На рисунке показан круг с радиусом 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()

удачи