【问题标题】:Drawing circles of variable size and position on a 2d animation在二维动画上绘制可变大小和位置的圆圈
【发布时间】:2014-05-12 12:11:23
【问题描述】:

我正在 Python 3.3 中使用 matplotlib。我有一个动画 2d 和 3d 窗口,我在其上绘制点。这些点代表物体,但不确定它们是否真的存在。所以我想在这些点周围画一个圆圈来显示不确定性。这种不确定性是变化的,所以底线是:我想在一个中心和半径可变的 2D 动画中绘制多个(可能是 0,可能是 100)圆。

我试过分散。 Scatter 看起来很有希望,直到我调整屏幕大小:scatter 的大小以像素为单位,与轴的大小无关。知道我该怎么做吗?

我尝试了以下分散代码:

#In the init
self.circles = self.ax.scatter([],[],[],c = 'b',alpha=0.6)
#In the animate function
self.circles.set_offsets([[10],[15]])    
self.circles._sizes = [2000]

中心点是正确的,在 x = 10 和 y = 15。但大小是以像素为单位的大小,与轴无关。例如,在这种情况下,我希望圆圈达到 x = 10 和 y = 20015。但事实并非如此。

当我调整窗口大小时,这会成为一个问题。

【问题讨论】:

  • 你的意思是大小以像素为单位?圈子大小?你能出示你的代码吗?
  • 在文本中添加了一些代码。
  • 这是分散的“特征”。看看 scatter 在下面是如何工作的,它只是路径对象的集合。我会对 Circle 补丁对象做同样的事情,你可以在数据单元中调整大小。
  • 我可以像使用散点图和线条一样使用圆吗?

标签: python python-3.x matplotlib


【解决方案1】:

绘制Collections比较快,所以我修改了scatter()返回的PathCollection对象的draw()函数。新的draw() 使用transData 计算每个圆圈的比例,它使用每个圆圈的大小作为直径。

import pylab as pl
import numpy as np
from matplotlib.collections import Collection
from matplotlib import transforms
import matplotlib.animation as animation

fig = pl.figure()

N = 40
x, y = np.random.rand(2, N)
color = np.random.rand(N)
r = np.random.rand(N) * 0.05 + 0.05

c = pl.scatter(x, y, s=r, c=color, alpha=0.5, animated=True)
pl.gca().set_aspect("equal")

def draw(self, renderer):
    if self._sizes is not None:
        m = self.axes.transData.get_matrix()
        self._transforms = [
            transforms.Affine2D().scale(m[0, 0]*x, m[1, 1]*x)
            for x in self._sizes]
    return Collection.draw(self, renderer)

c.draw = lambda renderer:draw(c, renderer)

def update_loc(n):
    global x2, y2, x, y
    n = n % 50
    if n == 0:
        x2, y2 = np.random.rand(2, N)
    x += (x2 - x) * 0.1
    y += (y2 - y) * 0.1
    c.set_offsets(np.c_[x, y])
    return c,

ani = animation.FuncAnimation(fig, update_loc, 2500, interval=50, blit=True)

pl.show()

这是动画的一帧:

【讨论】:

  • 非常好!我会尽快测试这个,如果它有效,你会得到绿色的“v”。
【解决方案2】:

Tcaswell 在上面的 cmets 中写下了答案,所以如果你想对此点赞,也请给他点赞。

解决方法是使用一个圆圈:http://matplotlib.org/api/artist_api.html#matplotlib.patches.Circle。这些工作与axis.plot和axis.scatter非常不同,因为要添加它们,您必须执行以下操作:

i = pyplot.Circle((item["x"],item["y"]), radius=item["inaccuracy"], fc='None'))
self.ax.add_patch(i)

然后删除它们:

i.remove()

tcaswell 还建议不要在绘制一组新圆之前删除每个圆,您也可以只移动 i 并调整其大小。这确实很有可能:只需更改iradiusxy 属性。我没有对此进行测试,但不难想象这会比删除所有现有圆圈并添加所有新圆圈更快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-19
    • 2019-10-14
    • 2015-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多