Git Product home page Git Product logo

streamjoy's Introduction

๐ŸŒˆ StreamJoy ๐Ÿ˜Š


build codecov PyPI version

Downloads GitHub stars


๐Ÿ”ฅ 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!

pip install 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!

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
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:

<AnyStream>
---
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!

himawari_stream.write()

๐Ÿ–‡๏ธ Connect streams

Connect multiple streams together to provide further context.

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.

pip install xarray cartopy matplotlib netcdf4
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 or best practices here. (Or maybe you're interested in the design--here)


โค๏ธ Made with considerable passion.

๐ŸŒŸ Appreciate the project? Consider giving a star!

streamjoy's People

Contributors

ahuang11 avatar zhihua-zheng avatar

Stargazers

Wytamma Wirth avatar  avatar Iury Simoes-Sousa avatar Navid C. Constantinou avatar Thomas Moore avatar Javed Ali avatar Dan Hooke avatar N. Sanchirico avatar Viet Nguyen avatar Marco Wolsza avatar Apu avatar Matt Savoie avatar Luis Lรณpez avatar xen0f0n avatar Leonard avatar Owen Lamont avatar Herculino Trotta avatar Jerry Noftz avatar  avatar Yoni Nachmany avatar Reinert Huseby Karlsen avatar echoxiangzhou avatar Fabian avatar Bhavik Talaviya  avatar Demetris Roumis avatar Emma Marshall avatar Tom Nicholas avatar ah avatar Deepak Cherian avatar Rishabh avatar Yordan Radev avatar  avatar Raphael Hagen avatar  avatar  avatar  avatar

Watchers

 avatar Kostas Georgiou avatar  avatar Apu avatar Thomas Moore avatar

streamjoy's Issues

Example when using Dask Gateway cluster (remote workers)

Is your feature request related to a problem? Please describe.

I'm not sure how to write the image files to scratch when using a remote dask cluster (e.g. a Dask Gateway cluster, where the workers are running on kubernetes and don't see the local filesystem)
https://nbviewer.org/gist/rsignell/9cd38657ca9ad20e55799bf41cb80de6

Is there a way to use streamjoy already with this type of Dask cluster?
If not, what would be the best way?
Can the scratch images be stored in memory or on object storage?

Max frames not respected

Something is not being propagated properly between:
df.streamjoy(max_frames=max_frames)
vs
stream(max_frames=max_frames)
vs
GifStream().write(max_frames=max_frames)
vs
GifStream(max_frames=max_frames).write()

import stream __init__() unexpected argument 'check_exists'

Wanted to start using streamjoy after looking at your NMME forecast example to produce something similar. Started of with your minimum working project:

Initial hurdle after pip installing steamjoy

Traceback / Example


TypeError Traceback (most recent call last)
Cell In[2], line 1
----> 1 from streamjoy import stream

File ~/miniconda3/envs/cda/lib/python3.11/site-packages/streamjoy/init.py:4
1 import logging
3 from ._utils import update_logger
----> 4 from .core import connect, stream
5 from .models import ImageText, Paused
6 from .renderers import (
7 default_holoviews_renderer,
8 default_pandas_renderer,
9 default_xarray_renderer,
10 )

File ~/miniconda3/envs/cda/lib/python3.11/site-packages/streamjoy/core.py:7
4 from pathlib import Path
5 from typing import Any, Callable, Literal
----> 7 from . import streams
8 from .serializers import serialize_appropriately
9 from .settings import extension_handlers

File ~/miniconda3/envs/cda/lib/python3.11/site-packages/streamjoy/streams.py:64
60 except ImportError:
61 pn = None
---> 64 class MediaStream(param.Parameterized):
65 """
66 An abstract class for creating media streams from various resources.
67 Do not use this class directly; use either GifStream or Mp4Stream.
68
69 Expand Source code to see all the parameters and descriptions.
70 """
72 resources = param.List(
73 default=None,
74 doc="The resources to render.",
75 )

File ~/miniconda3/envs/cda/lib/python3.11/site-packages/streamjoy/streams.py:177, in MediaStream()
166 threads_per_worker = param.Integer(
167 default=None,
168 bounds=(1, None),
169 doc="The number of threads to use per worker.",
170 )
172 show_progress = param.Boolean(
173 default=True,
174 doc="Whether to show the progress bar when rendering.",
175 )
--> 177 scratch_dir = param.Path(
178 doc="The directory to use for temporary files.", check_exists=False
179 )
181 in_memory = param.Boolean(
182 doc="Whether to store intermediate results in memory.",
183 )
185 fsspec_fs = param.Parameter(
186 doc="The fsspec filesystem to use for reading and writing.",
187 )

File ~/miniconda3/envs/cda/lib/python3.11/site-packages/param/init.py:1779, in Path.init(self, default, search_paths, **params)
1776 search_paths = []
1778 self.search_paths = search_paths
-> 1779 super(Path,self).init(default,**params)

TypeError: Parameter.init() got an unexpected keyword argument 'check_exists'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.