Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ahuang11/streamjoy

🌈😊 Enjoy animating images into GIFs and MP4s in parallel!
https://github.com/ahuang11/streamjoy

animate gif holoviews imageio matplotlib mp4 pandas streamjoy xarray

Last synced: 27 days ago
JSON representation

🌈😊 Enjoy animating images into GIFs and MP4s in parallel!

Awesome Lists containing this project

README

        

# 🌈 StreamJoy 😊

---

[![build](https://github.com/ahuang11/streamjoy/workflows/Build/badge.svg)](https://github.com/ahuang11/streamjoy/actions) [![codecov](https://codecov.io/gh/ahuang11/streamjoy/branch/master/graph/badge.svg)](https://codecov.io/gh/ahuang11/streamjoy) [![PyPI version](https://badge.fury.io/py/streamjoy.svg)](https://badge.fury.io/py/streamjoy)

[![Downloads](https://pepy.tech/badge/streamjoy)](https://pepy.tech/project/streamjoy) [![GitHub stars](https://img.shields.io/github/stars/ahuang11/streamjoy?style=flat-square)](https://img.shields.io/github/stars/ahuang11/streamjoy?style=flat-square)

---

## 🔥 Enjoy animating!

Streamjoy turns your images into animations using sensible defaults for fun, hassle-free creation.

It cuts down the boilerplate and time to work on animations, and it's simple to start with just a few lines of code.

Install it with just pip to start, blazingly fast!

```python
pip install streamjoy
```

Or, try out a basic web app version here:

https://huggingface.co/spaces/ahuang11/streamjoy

## 🛠️ Built-in features

- 🌐 Animate from URLs, files, and datasets
- 🎨 Render images with default or custom renderers
- 🎬 Provide context with a short intro splash
- ⏸ Add pauses at the beginning, end, or between frames
- ⚡ Execute read, render, and write in parallel
- 🔗 Connect multiple animations together

## 🚀 Quick start

### 🐤 Absolute basics

Stream from a list of images--local files work too!

```python
from streamjoy import stream

if __name__ == "__main__":
URL_FMT = "https://www.goes.noaa.gov/dimg/jma/fd/vis/{i}.gif"
resources = [URL_FMT.format(i=i) for i in range(1, 11)]
stream(resources, uri="goes.gif") # .gif, .mp4, and .html supported
```

### 💅 Polish up

Specify a few more keywords to:

1. add an intro title and subtitle
2. adjust the pauses
3. optimize the GIF thru pygifsicle

```python
from streamjoy import stream

if __name__ == "__main__":
URL_FMT = "https://www.goes.noaa.gov/dimg/jma/fd/vis/{i}.gif"
resources = [URL_FMT.format(i=i) for i in range(1, 11)]
himawari_stream = stream(
resources,
uri="goes_custom.gif",
intro_title="Himawari Visible",
intro_subtitle="10 Hours Loop",
intro_pause=1,
ending_pause=1,
optimize=True,
)
```

### 👀 Preview inputs

If you'd like to preview the `repr` before writing, drop `uri`.

Output:
```yaml

---
Output:
max_frames: 50
fps: 10
display: True
scratch_dir: streamjoy_scratch
in_memory: False
---
Intro:
intro_title: Himawari Visible
intro_subtitle: 10 Hours Loop
intro_watermark: made with streamjoy
intro_pause: 1
intro_background: black
---
Client:
batch_size: 10
processes: True
threads_per_worker: None
---
Resources: (10 frames to stream)
https://www.goes.noaa.gov/dimg/jma/fd/vis/1.gif
...
https://www.goes.noaa.gov/dimg/jma/fd/vis/10.gif
---
```

Then, when ready, call the `write` method to save the animation!

```python
himawari_stream.write()
```

### 🖇️ Connect streams

Connect multiple streams together to provide further context.

```python
from streamjoy import stream, connect

URL_FMTS = {
"visible": "https://www.goes.noaa.gov/dimg/jma/fd/vis/{i}.gif",
"infrared": "https://www.goes.noaa.gov/dimg/jma/fd/rbtop/{i}.gif",
}

if __name__ == "__main__":
visible_stream = stream(
[URL_FMTS["visible"].format(i=i) for i in range(1, 11)],
intro_title="Himawari Visible",
intro_subtitle="10 Hours Loop",
)
infrared_stream = stream(
[URL_FMTS["infrared"].format(i=i) for i in range(1, 11)],
intro_title="Himawari Infrared",
intro_subtitle="10 Hours Loop",
)
connect([visible_stream, infrared_stream], uri="goes_connected.gif")
```

### 📷 Render datasets

You can also render images directly from datasets, either through a custom renderer or a built-in one, and they'll also run in parallel!

The following example requires xarray, cartopy, matplotlib, and netcdf4.

```bash
pip install xarray cartopy matplotlib netcdf4
```

```python
import numpy as np
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from streamjoy import stream, wrap_matplotlib

@wrap_matplotlib()
def plot(da, central_longitude, **plot_kwargs):
time = da["time"].dt.strftime("%b %d %Y").values.item()
projection = ccrs.Orthographic(central_longitude=central_longitude)
subplot_kw = dict(projection=projection, facecolor="gray")
fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=subplot_kw)
im = da.plot(ax=ax, transform=ccrs.PlateCarree(), add_colorbar=False, **plot_kwargs)
ax.set_title(f"Sea Surface Temperature Anomaly\n{time}", loc="left", transform=ax.transAxes)
ax.set_title("Source: NOAA OISST v2.1", loc="right", size=5, y=-0.01)
ax.set_title("", loc="center") # suppress default title
plt.colorbar(im, ax=ax, label="°C", shrink=0.8)
return fig

if __name__ == "__main__":
url = (
"https://www.ncei.noaa.gov/data/sea-surface-temperature-"
"optimum-interpolation/v2.1/access/avhrr/201008/"
)
pattern = "oisst-avhrr-v02r01.*.nc"
stream(
url,
uri="oisst.gif",
pattern=pattern, # GifStream.from_url kwargs
max_files=30,
renderer=plot, # renderer related kwargs
renderer_iterables=[np.linspace(-140, -150, 30)], # iterables; central longitude per frame (30 frames)
renderer_kwargs=dict(cmap="RdBu_r", vmin=-5, vmax=5), # renderer kwargs
# cmap="RdBu_r", # renderer_kwargs can also be propagated for convenience
# vmin=-5,
# vmax=5,
)
```

Check out all the supported formats [here](https://ahuang11.github.io/streamjoy/supported_formats/) or best practices [here](https://ahuang11.github.io/streamjoy/best_practices/). (Or maybe you're interested in the design--[here](https://ahuang11.github.io/streamjoy/package_design/))

---

❤️ Made with considerable passion.

🌟 Appreciate the project? Consider giving a star!