накресліть коло з піплотом


158

дивно, що я не знайшов прямого опису того, як намалювати коло за допомогою matplotlib.pyplot (будь ласка, не пілаб), беручи за вхідний центр (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 спрямований в основному на побудову графіків (тобто ось деякі дані, викладіть їх на графік), а не на малювання, тому це може бути не зовсім прямо.
Томас К

Радіус точок розсіювання все частіше використовується для візуалізації даних. Діаграми Google називають їх «бульбашковими сюжетами». Gapminder.org - хороший приклад. Це є побудова, а не малювати. Я шукав у matplotlib github repo "бульбашку" та "розсіювання радіусу" безрезультатно, тому не думаю, що це в списку справ, що стосується додавання функції.
Беннет Браун

1
plt.scatter () приймає аргумент розміру. Ви можете передавати списки для x- і y-координат кіл, радіусів кіл та кольорів кіл. matplotlib.org/1.3.1/api/… . Моя помилка раніше, думаючи, що такої функціональності вже не було в matplotlib.
Беннет Браун

3
Відзначимо лише: plt.Circle(..)спрямовує на matplotlib.patches.Circle(). Тож рішення без піплоту було б circle = matplotlib.patches.Circle(..); axes.add_artist(circle).
ВажливістьBeingErnest

Відповіді:


203

Потрібно додати його до осей. A Circleє підкласом an Artist, а an 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, що корисно для обведення ключових результатів (наприклад, моя жовта точка даних).


4
Мені подобається ця відповідь, тому що ти "малюєш" коло, а не будуєш графіки. Хоча змова була б і моїм першим інстинктом.
samb8s

7
FYI: Схоже, клас Circle перемістився з matplotlib.pyplot на matplotlib.patches з моменту написання цієї відповіді.
pavon

6
Але але кружечки овальні!
rubenvb

1
@rubenvb бачити мій інший відповідь: stackoverflow.com/questions/9230389 / ...
Yann

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() засоби Отримайте поточну вісь

4
Ідеально! саме те, що мені потрібно було побачити зараз. Ваша "До речі" теж була дуже корисною! dir(fig)показує мені понад 30 методів "отримати", але gcaне має get_current_axisпсевдоніму. Ці відповіді фій чудові.
uhoh

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)

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


Що робить transform=ax.transAxes?
Лі

3
@Lee Це для кола в правому нижньому куті перетворіть дані в координатні осі, тобто (1,1) означає правий верхній кут в осях, (1,0) означає правий нижній кут тощо.
Syrtis Major

4
Це повинно бути частиною матплотлібу.
JustAC0der

Чи можна це використовувати mplleaflet? Якщо так, чи можете ви надати приклад?
Франсуа М.

@fmalaussena Оскільки цей фрагмент коду чистий matplotlib, я думаю, він повинен бути сумісний з тим, mplleafletщо я ніколи не намагався.
Сергій Майор

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

Або, якщо вам зручніше, подивіться на paths, http://matplotlib.sourceforge.net/users/path_tutorial.html


2
Тригонометричне рівняння кола і відхилення 0 tp 360, що означає 0 до 6,28319 радіанів mathopenref.com/coordparamcircle.html
Алекс Пуннен

19

Якщо ви маєте на меті "коло" підтримувати візуальне співвідношення сторін 1, незалежно від координат даних, ви можете скористатися методом raster (). 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 мають зменшувані радіуси знизу вліво вгорі праворуч.  Хоча графік має квадратну форму, вісь y має 10-кратний діапазон осі x.  Незважаючи на це, співвідношення сторін кіл на екрані дорівнює 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()

Удачі


0

Аналогічно для розкидання сюжету ви також можете використовувати звичайний сюжет із стилем лінії кола. За допомогою markersizeпараметра можна налаштувати радіус кола:

import matplotlib.pyplot as plt

plt.plot(200, 2, 'o', markersize=7)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.