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

Farewell to my most infamous package #163

Open
jbusecke opened this issue Jul 22, 2024 · 2 comments
Open

Farewell to my most infamous package #163

jbusecke opened this issue Jul 22, 2024 · 2 comments

Comments

@jbusecke
Copy link
Owner

jbusecke commented Jul 22, 2024

Hey everyone,

it is with a somewhat heavy heart that I have to announce that I am planning to retire this repo unless somebody else wants to take over the maintenance.

I have not had time to adequately maintain things here, and I wanted to apologize for the long wait times and unsolved issues/PRs that were a consequence of that.

Software maintenance is hard work, and even though I have made some of my most beloved animations with this package I actually believe there are now better options out there, and it presents a lot of overhead to maintain the custom logic here.

My current plan here is:

  • Wait for a bit to see if folks might want to take over the reigns here or have input on the future plans? cc @zmoon @tomchor
  • If nobody wants to take over: Add some recommendations on alternatives, archive the repo, and close all open issues/prs.

Thank you all for working and using this silly named package! Please let me know what you think about the plans here.

The alternatives I have in mind:

  • I have been making a lot of actual 3D work using geovists/pyvists Example 1 Example 2
  • streamjoy looks awesome and performant! Thanks @dcherian for the recommendation
  • For more custom animations (e.g. not just one 'layer' of pcolor, or faceted plots) I just recently played with matplotlibs FuncAnimation and I think that this will cover most of the usecases from folks here (it is a bit more code, but gives even more flexibility (and potentially better performance).
    • If people really like the xmovie interface, I would recommend refactoring the top level presets etc here to this (see example below)!

FuncAnimation Example

Example animation that overlays some contours over color on a "rotating" cartopy projection and produces this:
mymovie

import xarray as xr
import numpy as np

x = xr.DataArray(np.arange(360), dims=['x'])
y = xr.DataArray(np.arange(-90, 90), dims=['y'])
data_a = xr.DataArray(np.random.rand(360, 180, 100), dims=['x', 'y', 'time'], coords={'x':x, 'y':y}) * np.sin(np.deg2rad(y)*5)
data_b = data_a * np.cos(np.deg2rad(x))
ds = xr.Dataset({'a':data_a, 'b':data_b})

import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from matplotlib.animation import FuncAnimation

levels = [0.05, 0.95]
colors = ['orange']
plot_kwargs = dict(transform=ccrs.PlateCarree(), x='x', y='y')

def frame_to_lon_lat(frame, ds):
    # simples linear scaling. You can be much fancier here and add ramps, stops, etc...
    lon_range = np.linspace(0,360, len(ds.time))
    lat_range = np.linspace(0,180, len(ds.time))
    return lon_range[frame], lat_range[frame] 

# make initial figure
init_lon, _ = frame_to_lon_lat(0, ds)
fig, ax = plt.subplots(subplot_kw={'projection':ccrs.Robinson(central_longitude=init_lon)})

# # make initial figure
# fig, ax = plt.subplots()

# ax = plt.gca()
ds_frame = ds.isel(time=0)
mesh = ds_frame.a.plot(vmax=1, **plot_kwargs)
contour = ds_frame.b.plot.contour(colors=colors,levels=levels, add_colorbar=False, **plot_kwargs)
pp=[mesh, contour]
ax.coastlines()

def update_plot_frame(frame, ds, ax):
    # You can probably update these more efficiently by just replacing the mesh.properties()['data'] but 
    # lets use the easiest thing for now
    # just make some new mesh and update the old one from that
    ds_frame = ds.isel(time=frame).squeeze()

    # How do i remove the mesh?
    # seems like I do not have to?
    pp[0].remove()

    # the contours need to be removed (otherwise they will all overplot each other)
    pp[1].remove()

    # # set projection to rotate
    lon_frame, _ = frame_to_lon_lat(frame, ds)
    ax.projection = ccrs.Robinson(central_longitude=lon_frame)
    
    pp[0] = ds_frame.a.plot(vmax=1, add_colorbar=False, **plot_kwargs)
    pp[1] = ds_frame.b.plot.contour(colors=colors,levels=levels, add_colorbar=False, **plot_kwargs)
    return pp

fa = FuncAnimation(fig, update_plot_frame, 200, fargs=[ds, ax])
fa.save("bye_bye_xmovie.gif")
@tomchor
Copy link
Contributor

tomchor commented Jul 28, 2024

Sad to read this announcement!

For me the simplicity of using xarray to write images in parallel and string them together is unparalleled. Every other alternative that I've tried to use either ends up trying to reinvent the wheel in some way or I end up having to write too much code, so maintenance here will be missed.

FYI, a few months ago I actually forked this repo with a different name just to keep things functional and deal with some issues that weren't getting responses here: https://github.com/tomchor/xanimations. I'm not planning on adding features, just keep things from breaking. That said, people are obviously welcome to use that and if you want write access to that repo to help with development, let me know and I'd be glad to give it.

Adding to the list of alternatives, I've used hvplot a few times before and it's really good for interactively investigating data. It also has very a handy xarray API. The one issue with it (as a potential replacement for xmovie) is that it's really made to be an interactive exploration package using bokeh as a backend. Last I checked it could export things as an mp4, but it's really not meant for that, so sometimes the export doesn't go smoothly. But hey, if you want to do some interactive plotting, this is definitely a great option.

@jbusecke
Copy link
Owner Author

Thanks for the kind words @tomchor. If you would be willing to maintain here, I am happy to make you an admin (you could merge in the changes from xanimations, and maybe consider a name change?).

Also happy to have a quick chat about potential to keep things alive here, but maybe just prune out some of the functionality? Or even refactor on top of FuncAnimation... ah geez now I am nerd sniping myself haha. But either way, I just want to do what is best for the users, while freeing up some of my time. Let me know.

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

No branches or pull requests

2 participants