用pyplot绘制一个圆圈

Max*_* Li 134 python matplotlib

令人惊讶的是,我没有找到关于如何使用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()
Run Code Online (Sandbox Code Playgroud)

......但仍然无法正常工作.

Yan*_*ann 177

您需要将其添加到轴.A Circle是a的子类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')
Run Code Online (Sandbox Code Playgroud)

这导致下图:

第一个圆位于原点,但默认情况下clip_onTrue这样,因此当圆形延伸到圆形时,圆形会被修剪axes.第三个(绿色)圆圈显示当你不剪辑时会发生什么Artist.它延伸到轴之外(但不超出图形,即图形尺寸不会自动调整以绘制所有艺术家).

x,y和radius的单位默认对应于数据单位.在这种情况下,我没有在我的轴上绘制任何东西(fig.gca()返回当前轴),并且由于从未设置过限制,因此它们默认为从0到1的x和y范围.

这是示例的延续,显示单位如何重要:

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')
Run Code Online (Sandbox Code Playgroud)

这导致:

您可以看到我如何设置第二个圆的填充False,这对于环绕关键结果非常有用(比如我的黄色数据点).

  • 仅供参考:看起来Circle类已​​从matplotlib.pyplot转移到matplotlib.patches,因为这个答案是写的. (7认同)
  • 但是但是圈子是椭圆形的! (6认同)
  • 我喜欢这个答案,因为你"画"了一个圆圈,而不是绘图.虽然密谋也是我的第一直觉. (4认同)
  • @rubenvb请参阅我的其他答案:http://stackoverflow.com/questions/9230389/why-is-matplotlib-plotting-my-circles-as-ovals/9232513#9232513 (2认同)
  • @pavon对我来说`matplotlib.pyplot.Circle == matplotlib.patches.Circle`的值为`True`,因此它们可能是别名。 (2认同)

小智 56

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

接受答案的快速浓缩版本,可快速将圆圈插入现有情节中.请参阅接受的答案和其他答案以了解详细信息.

顺便说说:

  • gcf() 意味着获得当前数字
  • gca() 意味着获取当前轴

  • 你实际上可以做`plt.gca()`而不是`plt.gcf().gca()` (5认同)
  • 完善!正是我现在需要看到的.你的'顺便'也非常有用!`dir(fig)`给我看了30多个'get'方法,但`gca`没有`get_current_axis`别名.这些fyi答案很精彩. (3认同)

Syr*_*jor 37

如果你想绘制一组圆圈,你可能想看到这篇文章这个要点(有点新).帖子提供了一个名为的功能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)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 这应该是matplotlib的一部分. (4认同)
  • @Lee对于右下角的圆圈,将数据转换为轴坐标,即(1,1)表示轴的右上角,(1,0)表示右下角等. (2认同)

ev-*_*-br 19

#!/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()
Run Code Online (Sandbox Code Playgroud)

或者,如果您愿意,请查看paths,http://matplotlib.sourceforge.net/users/path_tutorial.html

  • 圆和度数 0 tp 360 的三角方程,转换为 0 到 6.28319 弧度 http://www.mathopenref.com/coordparamcircle.html (2认同)

Ben*_*own 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()
Run Code Online (Sandbox Code Playgroud)

图像是散点图. 沿y = 10x线的五个圆从左下到右上具有减小的半径. 尽管图形是方形的,但y轴的x轴范围是10倍. 即便如此,圆圈的纵横比在屏幕上为1.


Evg*_*eev 9

扩展已接受的答案以用于常见用例.特别是:

  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()
Run Code Online (Sandbox Code Playgroud)

注意两者之间的区别ax.add_patch(..)ax.add_artist(..):两者之间只有前者使自动调节机器考虑到圆圈(参考:讨论),所以运行上面的代码后我们得到:

add_patch(..)vs add_artist(..)

另见:set_aspect(..)文档.


小智 7

我看到了使用 (.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)
Run Code Online (Sandbox Code Playgroud)

使用线性渐进点的简单同心圆图

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')
Run Code Online (Sandbox Code Playgroud)

分类问题的圆圈点。

  • scikit-learn 有一个 `make_blobs` 函数:https://scikit-learn.org/stable/modules/ generated/sklearn.datasets.make_blobs.html (2认同)