You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib技术咨询:如何在3D箭袋图动画中删除旧参考框架线条

How to Update 3D Quiver Plots in Matplotlib by Removing Old Arrows

Great question! The issue with your current code is that every time timerTick_Event runs, it adds new 3D quiver arrows without removing the old ones—over time, this clogs up the plot with overlapping arrows. There are two clean ways to fix this, depending on whether you prefer to delete old objects or update existing ones (the latter is more efficient).

Method 1: Remove Old Quiver3D Objects Before Adding New Ones

Matplotlib's 3D quiver is an instance of Quiver3D, so we can scan the axes' children for this type and remove them before drawing new arrows. Here's how to modify your code:

First, import the Quiver3D type at the top:

from matplotlib.quiver import Quiver3D

Then update your timerTick_Event function to remove old arrows first:

def timerTick_Event(i):
    #%% DATA SIMULATION
    temp1 = np.array([rnd.uniform(-1.0, 1.0), rnd.uniform(-1.0, 1.0), rnd.uniform(-1.0, 1.0)]).astype(float)
    temp1 = temp1 / np.linalg.norm(temp1)
    v2 = np.array([rnd.uniform(-1.0, 1.0), rnd.uniform(-1.0, 1.0), rnd.uniform(-1.0, 1.0)]).astype(float)
    v2 = v2 / np.linalg.norm(v2)
    v3 = np.cross(temp1, v2)
    v3 = v3 / np.linalg.norm(v3)
    v1 = np.cross(v2, v3)
    v1 = v1 / np.linalg.norm(v1)
    mat = np.column_stack((v1, v2, v3))

    #%% REMOVE OLD ARROWS
    ax = plt.gca()
    # Iterate through children and remove all Quiver3D objects
    for child in list(ax.get_children()):  # Use list() to avoid modifying the list while iterating
        if isinstance(child, Quiver3D):
            child.remove()

    #%% DATA REPRESENTATION
    ax.quiver(0, 0, 0, mat[0,0], mat[0,1], mat[0,2], color="r")
    ax.quiver(0, 0, 0, mat[1,0], mat[1,1], mat[1,2], color="g")
    ax.quiver(0, 0, 0, mat[2,0], mat[2,1], mat[2,2], color="b")
    # Remove plt.show() here—FuncAnimation handles rendering

Note: We use list(ax.get_children()) to create a copy of the children list, so we don't get errors from modifying the list while iterating over it. Also, remove the plt.show() call inside the event function, since FuncAnimation manages the plot display.

Method 2: Update Existing Quiver Objects (More Efficient)

Instead of deleting and recreating arrows every time, we can update the data of the existing quiver objects directly using the set_UVC method. This is better for performance, especially with frequent updates.

Here's the modified complete code:

import random as rnd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

def timerTick_Event(i):
    #%% DATA SIMULATION
    temp1 = np.array([rnd.uniform(-1.0, 1.0), rnd.uniform(-1.0, 1.0), rnd.uniform(-1.0, 1.0)]).astype(float)
    temp1 = temp1 / np.linalg.norm(temp1)
    v2 = np.array([rnd.uniform(-1.0, 1.0), rnd.uniform(-1.0, 1.0), rnd.uniform(-1.0, 1.0)]).astype(float)
    v2 = v2 / np.linalg.norm(v2)
    v3 = np.cross(temp1, v2)
    v3 = v3 / np.linalg.norm(v3)
    v1 = np.cross(v2, v3)
    v1 = v1 / np.linalg.norm(v1)
    mat = np.column_stack((v1, v2, v3))

    #%% UPDATE EXISTING QUIVERS
    # Update the direction vectors for each axis quiver
    u.set_UVC(mat[0,0], mat[0,1], mat[0,2])
    v.set_UVC(mat[1,0], mat[1,1], mat[1,2])
    w.set_UVC(mat[2,0], mat[2,1], mat[2,2])

# Initialize the figure and axes
f1 = plt.figure(1)
ax = f1.add_subplot(projection='3d')

# Create initial quiver objects (we'll update these later)
u = ax.quiver(0, 0, 0, 0, 0, 0, color="r")
v = ax.quiver(0, 0, 0, 0, 0, 0, color="g")
w = ax.quiver(0, 0, 0, 0, 0, 0, color="b")

# Legend setup (unchanged)
ax.plot([], [], [], color="r", label="X")
ax.plot([], [], [], color="g", label="Y")
ax.plot([], [], [], color="b", label="Z")

ax.set_xlim(-1.1, 1.1); ax.set_ylim(-1.1, 1.1); ax.set_zlim(-1.1, 1.1)
ax.set_xlabel("X_AXIS"); ax.set_ylabel("Y_AXIS"); ax.set_zlabel("Z_AXIS")
ax.legend();

timerTickInterval = 1000
ani = FuncAnimation(f1, timerTick_Event, interval=timerTickInterval)
plt.show()

This approach reuses the same quiver objects throughout the animation, so there's no need to delete anything—we just refresh their data each time the event triggers. This is the recommended method for smooth, efficient animations.

内容的提问来源于stack exchange,提问作者eljamba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 21:12:29