我在Python 3.3中使用matplotlib。我有一个动画的2D和3D窗口,我在上面绘制点。这些点代表对象,但不确定它们实际上是在那里。所以我想围绕这些点绘制一个圆圈来显示不确定性。这种不确定性是变化的,所以底线:我想在具有可变中心和可变半径的2D动画中绘制多个(可能是0,可能是100)圆圈。
我试过散布。 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。但事实并非如此。
当我调整窗口大小时,这会成为一个问题。
答案 0 :(得分:2)
绘图Collections
速度更快,因此我修改了draw()
返回的PathCollection
对象的scatter()
函数。新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()
这是动画的一个框架:
答案 1 :(得分:0)
Tcaswell在上面的评论中写下了这个答案,所以如果你想提出这个问题,那么也要投票给他。
修复方法是使用圆圈:http://matplotlib.org/api/artist_api.html#matplotlib.patches.Circle。这些工作与添加它们的sens中的axis.plot和axis.scatter非常不同,您必须执行以下操作:
i = pyplot.Circle((item["x"],item["y"]), radius=item["inaccuracy"], fc='None'))
self.ax.add_patch(i)
并删除它们:
i.remove()
tcaswell还建议,在绘制一组新圆圈之前,您还可以移动并调整大小,而不是移除每个圆圈。这确实很有可能:只需更改radius
的{{1}}和xy
属性即可。我没有对此进行测试,但不难想象这会比删除所有现有的圈子并添加所有新圈子更快。