如何对动画散点图中的节点重新排序(更改深度)

2024-06-16 11:22:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我在散点图上有一堆重叠的点。我正在使用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没有深入的了解,我删除它们的尝试至今都失败了。你知道吗


Tags: thetoinimportformatplotlibupdaterange
2条回答

为了将红点放在前面,您需要对红点最后出现的数据进行排序。在下面的代码中,它不是按颜色对点进行排序,而是在每次调用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)

您可以有第二个scatter绘图,红色,具有更高的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)

Edit: Updated to also run on Python 3.6.3, matpotlib 2.1.0

我不知道为什么,但似乎如果不保留对FuncAnimation的引用,它在python3.6上就不起作用。感谢乔尔(评论)的注意。你知道吗

相关问题 更多 >