Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Matplotlib upgrade #270

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

zombie-einstein
Copy link
Contributor

@zombie-einstein zombie-einstein commented Dec 13, 2024

Hey @sash-a, thought I'd grab a look at #253.

Changes here update Matplotlib version and then makes changes to pass type checking, so it builds and passes tests.

But ...

The new API now requires that the animation update function returns a list of artists that have been updated, these are objects returned from plotting calls like a plot object, or text box (see the table here). The state/data of these objects can be updated without redrawing the whole thing.

I've done this rubiks cube environment:

# Create the first frame of the plot and return a list of drawn image artists
images = self._draw(ax, states[0])

def make_frame(state: State) -> Sequence[Artist]:
    # Update the data in each image from the state
    for i, image in enumerate(images):
        image.set_data(state.cube[i])
    # Return the updated images
    return images

# Create the animation object.
self._animation = matplotlib.animation.FuncAnimation(
    fig,
    make_frame,
    frames=states,
    interval=interval,
)

Doing this for all environments is easier for some than others given how they've been written, it means passing all the relevant artists to the animate function when the plot is created, and then correctly updating them inside the update function.

I think the animations will still work as is, as they still generally update the axes by reference inside the animation function, it's just less efficient then the new API that just updates the relevant artists.

@sash-a
Copy link
Collaborator

sash-a commented Dec 15, 2024

Wow this is an awesome addition, thanks @zombie-einstein!

Which environments are still remaining?

Also I think the way you've done it with make_frame looks good, but I have no experience with the new API

@zombie-einstein
Copy link
Contributor Author

zombie-einstein commented Dec 16, 2024

Which environments are still remaining?

Apart from rubix cube they all need a look at, with varying degrees of complexity. I think the general pattern needs to be something like a draw function that draws the first frame (and also draws the individual frames via the render method), and returns any actors that will be updated during the animation, then use this to initialise the first frame and update actors inside the update-func.

Some also currently have actors that are created dynamically during plotting I've been trying to work out the best pattern for, in some cases it seems it would be more efficient to initialise all the actors ahead of time, and update their states as needed. E.g. for the sudoko environment initialise all the text actors and update the text during animation (rather than create them on the fly).

So there's a decent chunk of work to refactor all the plots. One option could be merge something like this PR, which will updated the requirement and passes linting/tests, and still create plots (just less efficiently), and then incrementally update the individual viewers in separate PRs to make best use of the new API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants