Skip to content Skip to sidebar Skip to footer

Dynamically Update Ax.text Position In 3d Scatter/point Plot's Using Funcanimation

I've been trying to annotate individual points in a 3d scatter plot and getting them updated dynamically. Referred to this: Matplotlib: Annotating a 3D scatter plot But I'm using F

Solution 1:

The easiest is probably to create 2D text.

text = ax.text2D(x, y, text)

And then to update its projected coordinates.

x2, y2, _ = proj3d.proj_transform(seq_x, seq_y, seq_z, ax.get_proj())
text.set_position((x2,y2))

Full working code:

import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as p3
from mpl_toolkits.mplot3d import proj3d
import matplotlib.animation as animation

classSimulator:

    def__init__(self):
        s_1 = ((0.5, 0.5, 0.0), (0.5,0.5,0.2), (0.5,0.5,1.0), (1.9,0.5,2.0))
        s_2 = ((1.9, 0.5, 0.0), (1.9,0.5,0.2), (1.9,0.5,1.0), (1.9,1.9,2.0))
        s_3 = ((1.2, 1.2, 0.0), (1.2,1.2,0.2), (1.2,1.2,1.0), (1.2,1.2,2.5))
        s_4 = ((0.5, 1.9, 0.0), (0.5,1.9,0.2), (0.5,1.9,1.0), (0.5,0.5,2.0))
        s_5 = ((1.9, 1.9, 0.0), (1.9,1.9,0.2), (1.9,1.9,1.0), (0.5,1.9,2.0))

        self.data = {
        's_1': {'raw': s_1},
        's_2': {'raw': s_2},
        's_3': {'raw': s_3},
        's_4': {'raw': s_4},
        's_5': {'raw': s_5}
        }

        ###### Setup ######
        self.fig = plt.figure()
        self.ax = self.fig.add_subplot(111, projection='3d')
        # Setting the axes properties
        self.ax.set_xlim3d([0.0, 3.0])
        self.ax.set_xlabel('X')

        self.ax.set_ylim3d([0.0, 3.0])
        self.ax.set_ylabel('Y')

        self.ax.set_zlim3d([0.0, 3.0])
        self.ax.set_zlabel('Z')

        for point,dic in self.data.items():
            dic['x'] = []
            dic['y'] = []
            dic['z'] = []
            dic['length'] = len(dic['raw'])
            for coords in dic['raw']:
                dic['x'].append(coords[0])
                dic['y'].append(coords[1])
                dic['z'].append(coords[2])

        # Interval in milliseconds
        self.anim = animation.FuncAnimation(self.fig, self.update, init_func=self.setup, interval=1000)

        plt.show()


    defsetup(self):
        plots = []

        for point,dic in self.data.items():
            dic['plot'] = self.ax.scatter3D([], [], [], c='red', picker = True)
            dic['label'] = self.ax.text2D(dic['x'][0], dic['y'][0], point, zorder=1, color='k')

    defupdate(self, i):

        plots = []

        seq_x = []
        seq_y = []
        seq_z = []

        for point,dic in self.data.items():
            if i < dic['length']:

                seq_x = dic['x'][i]
                seq_y = dic['y'][i]
                seq_z = dic['z'][i]
                dic['plot']._offsets3d = [seq_x], [seq_y], [seq_z]

                #### Set position of text
                x2, y2, _ = proj3d.proj_transform(seq_x, seq_y, seq_z, self.ax.get_proj())
                dic['label'].set_position((x2,y2))

            else:
                self.anim.event_source.stop()
                print('Simulation ended.')
        return plots


Simulator()

Post a Comment for "Dynamically Update Ax.text Position In 3d Scatter/point Plot's Using Funcanimation"