【问题标题】:plot a circle with pyplot用 pyplot 画一个圆
【发布时间】:2012-03-02 04:57:44
【问题描述】:

令人惊讶的是,我没有找到关于如何使用 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 存储库中搜索“气泡”和“散射半径”无济于事,所以就添加功能而言,我认为这不在待办事项列表中。
  • plt.scatter() 确实采用了大小参数。您可以传递圆的 x 和 y 坐标、圆的半径和圆的颜色的列表。 matplotlib.org/1.3.1/api/… 。我之前的错误是认为 matplotlib 中还没有这样的功能。
  • 顺便提一下:plt.Circle(..) 指向matplotlib.patches.Circle()。所以没有 pyplot 的解决方案是circle = matplotlib.patches.Circle(..); axes.add_artist(circle).

标签: python matplotlib


【解决方案1】:

您需要将其添加到坐标区。 CirclePatch 的子类,axes 具有 add_patch 方法。 (也可以使用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_patch(circle1)
ax.add_patch(circle2)
ax.add_patch(circle3)

fig.savefig('plotcircles.png')

结果如下图:

第一个圆圈位于原点,但默认情况下clip_onTrue,因此当圆圈超出axes 时,它会被剪裁。第三个(绿色)圆圈显示当您不剪辑Artist 时会发生什么。它超出坐标轴(但不超出图形,即图形大小不会自动调整以绘制所有艺术家)。

默认情况下,x、y 和半径的单位对应于数据单位。在这种情况下,我没有在我的坐标轴上绘制任何东西(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_patch(circle1)
ax.add_patch(circle2)
ax.add_patch(circle3)
fig.savefig('plotcircles2.png')

导致:

您可以看到我如何将第二个圆圈的填充设置为 False,这对于包围关键结果(如我的黄色数据点)很有用。

【讨论】:

  • 我喜欢这个答案,因为您是在“画”一个圆圈,而不是在绘图。虽然策划也是我的第一直觉。
  • 仅供参考:自编写此答案以来,Circle 类似乎已从 matplotlib.pyplot 移至 matplotlib.patches。
  • 但是但是圆圈是椭圆的!
  • @rubenvb 看到我的另一个答案:stackoverflow.com/questions/9230389/…
  • @pavon 对于我来说,matplotlib.pyplot.Circle == matplotlib.patches.Circle 的计算结果为 True,所以它们可能是别名。
【解决方案2】:
import matplotlib.pyplot as plt

circle1 = plt.Circle((0, 0), 0.2, color='r')
plt.gca().add_patch(circle1)

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

顺便说一句:

  • gca() 表示获取当前轴

【讨论】:

  • 完美!正是我现在需要看到的。你的“顺便说一句”也很有帮助! dir(fig) 向我展示了 30 多种“获取”方法,但 gca 没有 get_current_axis 别名。这些仅供参考的答案很棒。
  • 您实际上可以使用plt.gca() 而不是plt.gcf().gca()
【解决方案3】:

如果您想绘制一组圆圈,您可能希望看到this postthis gist(有点新)。该帖子提供了一个名为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 是做什么的?
  • @Lee 右下角的圆,将数据转换为坐标轴坐标,即(1,1)表示坐标轴的右上角,(1,0)表示右下角角落等
  • 这应该是 matplotlib 的一部分。
  • 这个可以和mplleaflet一起使用吗?如果是这样,你能举个例子吗?
  • @fmalaussena 由于这段代码 sn-p 是纯 matplotlib,我想它应该与 mplleaflet 兼容,尽管我从未尝试过。
【解决方案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()

或者,如果您愿意,请查看paths、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()

【讨论】:

    【解决方案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(..)之间的区别:两者中,只有前者使自动缩放机械考虑圆(参考:discussion ),所以在运行上面的代码后我们得到:

    另请参阅:set_aspect(..) documentation

    【讨论】:

    • 在python3中,需要去掉fig, ax = plt.subplots(),否则会得到两个窗口(一个是空白的)。
    【解决方案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)
    

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

    【讨论】:

      【解决方案8】:

      与散点图类似,您也可以使用带有圆线样式的普通图。使用markersize参数可以调整圆的半径:

      import matplotlib.pyplot as plt
      
      plt.plot(200, 2, 'o', markersize=7)
      

      【讨论】:

        【解决方案9】:

        你好,我写了一个画圆的代码。 它将有助于绘制各种圆圈。 The image shows the circle with radius 1 and center at 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()
        

        祝你好运

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-10-15
          • 1970-01-01
          • 1970-01-01
          • 2011-02-28
          • 2012-04-27
          • 2014-10-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多