0

I am trying to plot an animation of the motion of several different ships in a North-East frame. Each ship is identified by a circle marker, color, and an ID. The vessel information is stored in a list of Vessel objects each with a positions attribute which stores north and east coordinates.

I only want to keep the newest ship's position, so all earlier points should be cleared.

What I have written so far plots the dots but I cannot find a way to specify additional parameters such as name and color arguments. I would prefer to not have to create an individual line object for each vessel because the IDs are not necessarily sorted and there may be a need for static object in the future which are stored in a separate list.

The code I have so far is

def plot_animation(vessels, objects, ts=10, n_min=3, **kwargs):
    import matplotlib.animation as animation

    """Plots the results of a simulation
    input:
        vessels: List of `Vessel()` type
        n_min: The number of minutes between each position scatter point
        **kwargs: Keyword arguments for the plotting commands

    output:
        None
    """
    pos_marker = kwargs.get("pos_marker", "o") # options
    pos_marker_size = kwargs.get("pos_marker_size", 50)

    frames = len(vessels[0].get_positions()) # number of simulation time-points
    axis_min = 0
    axis_max = 0
    for v in vessels: # for determining axis bounds
        positions = v.get_positions()
        axis_min = min(min([min(pos) for pos in positions]), axis_min)
        axis_max = max(max([max(pos) for pos in positions]), axis_max)

    fig = plt.figure()
    ax = fig.add_subplot(
        111, autoscale_on=False, xlim=(axis_min, axis_max), ylim=(axis_min, axis_max)
    )
    ax.set_aspect("equal")
    ax.grid()
    ax.set_xlabel("East [km]")
    ax.set_ylabel("North [km]")

    (line,) = ax.plot([], [], "o")

    def init():
        line.set_data([], [])
        return (line,)

    def animate(i):
        x = []
        y = []

        for v in vessels:
            positions = v.get_positions()
            north = positions[i].north
            east = positions[i].east
            x.append(east)
            y.append(north)
        line.set_data(x, y)
        return (line,)

    ani = animation.FuncAnimation(
        fig, animate, frames=frames, init_func=init, blit=True
    )
    plt.show()
Morten Nissov
  • 392
  • 3
  • 13
  • All markers in a Line2D are the same colors, so if you want points of different color, you will have to go a different route. Either individual Line2D or using scatter(). For the names, you'll have to create individual text objects are update their position at the same time as the points – Diziet Asahi Nov 08 '20 at 19:54
  • Writing `ax.scatter([], [])` actually keeps returning errors for me, I had originally thought of doing this. – Morten Nissov Nov 08 '20 at 21:42
  • Here is a post on animating a scatter plot https://stackoverflow.com/questions/61012851/animating-monte-carlo-method-pi-color-dots-diferently/61013189#61013189 and here is one one animating an annotation https://stackoverflow.com/questions/18351932/animate-points-with-labels-with-matplotlib – Diziet Asahi Nov 08 '20 at 21:59

0 Answers0