Python 如何对动画散点图中的节点重新排序(更改深度)
我在散点图中有一堆重叠的点。我正在使用Python 如何对动画散点图中的节点重新排序(更改深度),python,animation,matplotlib,Python,Animation,Matplotlib,我在散点图中有一堆重叠的点。我正在使用FuncAnimation创建动画。在连续的帧中,我想改变出现在其他帧前面的帧 作为一个简单的MCVE,考虑下面的代码,其中每个帧使不同的点集成为红色。但是,这些红点通常会被其他点遮挡。我想把这些红点放在前面 import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation import random def update(time, plotted_points,
FuncAnimation
创建动画。在连续的帧中,我想改变出现在其他帧前面的帧
作为一个简单的MCVE,考虑下面的代码,其中每个帧使不同的点集成为红色。但是,这些红点通常会被其他点遮挡。我想把这些红点放在前面
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random
def update(time, plotted_points, N):
#in here I would like to update the order that the points are plotted in. I would like the red points to come to the front.
color_change_indices = set(random.choices(range(N), k=1000))
colors = ['red' if n in color_change_indices else 'gray' for n in range(N)]
plotted_points.set_color(colors)
return plotted_points
def animate(N):
x = [random.random() for val in range(N)]
y = [random.random() for val in range(N)]
fig = plt.figure()
ax = fig.add_subplot(111)
plotted_points = ax.scatter(x, y, color='gray')
fargs = (plotted_points, N)
ani = FuncAnimation(fig, update, frames = range(100), fargs = fargs)
plt.show()
animate(10000)
我可以改变他们的颜色。我可以移动他们的坐标。但是,到目前为止,我无法修改它们的相对深度
到目前为止,我最好的想法是,也许我应该删除绘制的点,然后重新打印它们。但是我对matplotlib没有深入的了解,我试图删除它们的尝试到目前为止都失败了。您可以使用第二个
散点
绘图,红色且具有更高的zorder
,并更新其点:
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random
plt.ion()
def update(time, red_plotted_points, points, N):
indexes = set([random.choice(range(N)) for i in range(int(N/2))]) # for instance!
new_points = [points[i] for i in indexes]
red_plotted_points.set_offsets(new_points)
def animate(N):
x = [random.random() for val in range(N)]
y = [random.random() for val in range(N)]
points = [[x[i], y[i]]for i in range(N)]
fig = plt.figure()
ax = fig.add_subplot(111)
plotted_points = ax.scatter(x, y, color='gray', zorder=1)
red_plotted_points = ax.scatter([], [], color='red', zorder=2) # starts empty
fargs = (red_plotted_points, points, N)
ani = FuncAnimation(fig, update, frames=range(100), fargs=fargs,
interval=200, repeat=True)
ani._start()
fig.show()
return fig, ani
if __name__ == '__main__':
fig, ani = animate(100)
(python 2.7.14,matplotlib 2.1.1)
编辑:更新为也在Python 3.6.3、matpotlib 2.1.0上运行
我不知道为什么,但如果不保留对
FuncAnimation
的引用,它似乎在Python 3.6上不起作用。感谢Joel(评论)的注意。为了让红点排在前面,您需要对红点最后出现的数据进行排序。在下面的代码中,它不是按颜色对点进行排序,而是在每次调用update时对数据进行洗牌,并用红色绘制最后1000个点
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import random
import numpy as np # np.random.shuffle
def update(time, plotted_points):
# Extract data and colors
data = plotted_points.get_offsets()
colors = plotted_points.get_facecolor()
# shuffle the data [N, 2] along the first axis
np.random.shuffle(data)
# Set shuffled data and reset colors
plotted_points.set_offsets(data)
plotted_points.set_color(colors)
return plotted_points
def animate(N):
x = [random.random() for val in range(N)]
y = [random.random() for val in range(N)]
fig = plt.figure()
ax = fig.add_subplot(111)
# Need to define colors at first.
colors = ['red' if idx < 1000 else 'gray' for idx in range(N)]
colors.reverse()
plotted_points = ax.scatter(x, y, color=colors)
fargs = (plotted_points,)
ani = FuncAnimation(fig, update, frames = range(100), fargs = fargs)
plt.show()
animate(10000)
导入matplotlib.pyplot作为plt
从matplotlib.animation导入FuncAnimation
随机输入
将numpy作为np#np.random.shuffle导入
def更新(时间、打印点):
#提取数据和颜色
数据=绘制的点。获取偏移量()
颜色=打印的点。获取面颜色()
#沿第一个轴移动数据[N,2]
np.random.shuffle(数据)
#设置无序数据并重置颜色
打印点。设置偏移(数据)
打印点。设置颜色(颜色)
返回点
定义动画(N):
x=[random.random()表示范围(N)内的val]
y=[random.random()表示范围(N)内的val]
图=plt.图()
ax=图添加_子批次(111)
#首先需要定义颜色。
颜色=[“红色”如果idx<1000,否则“灰色”表示idx在范围内(N)]
颜色。反向()
绘制点=最大散射(x,y,颜色=颜色)
fargs=(标绘点)
ani=动画(图,更新,帧=范围(100),法格斯=法格斯)
plt.show()
动画制作(10000)
很抱歉,但是当我在Python 3.6中运行这个时[在将N/2
替换为int(N/2)
]之后]我似乎没有得到任何输出。我不明白为什么,但是如果你在animatpotlib 2.1.0的函数末尾添加return fig,ani
,并使fig,ani=animatpotlib(100)
它在Python 3.6.3中设置动画。也许这与内存中的动画持久性有关,但我真的不知道(返回1或None
不起作用,返回导致namererror
的内容会奇怪地启用动画)。此外,如果您使用的是Ipython控制台,我不知道内联图是否允许动画。我原以为plt.ion()
会解决这个问题,但您可能需要在Ipython控制台上调用%matplotlib
,将后端更改为默认值(在我的例子中是Qt5Agg)。