{"id":16860082,"url":"https://github.com/ahuang11/streamjoy","last_synced_at":"2025-04-11T16:40:37.467Z","repository":{"id":224416021,"uuid":"763212328","full_name":"ahuang11/streamjoy","owner":"ahuang11","description":"🌈😊 Enjoy animating images into GIFs and MP4s in parallel!","archived":false,"fork":false,"pushed_at":"2024-06-06T15:28:53.000Z","size":2131,"stargazers_count":46,"open_issues_count":9,"forks_count":2,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-06-11T16:56:20.554Z","etag":null,"topics":["animate","gif","holoviews","imageio","matplotlib","mp4","pandas","streamjoy","xarray"],"latest_commit_sha":null,"homepage":"https://ahuang11.github.io/streamjoy/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ahuang11.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"docs/supported_formats.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-25T20:48:01.000Z","updated_at":"2024-06-12T18:06:02.105Z","dependencies_parsed_at":"2024-06-12T18:06:01.831Z","dependency_job_id":"3fdaec32-83c9-4120-becb-9f9cfe224fb8","html_url":"https://github.com/ahuang11/streamjoy","commit_stats":null,"previous_names":["ahuang11/streamwee"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahuang11%2Fstreamjoy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahuang11%2Fstreamjoy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahuang11%2Fstreamjoy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahuang11%2Fstreamjoy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ahuang11","download_url":"https://codeload.github.com/ahuang11/streamjoy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248442011,"owners_count":21104115,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["animate","gif","holoviews","imageio","matplotlib","mp4","pandas","streamjoy","xarray"],"created_at":"2024-10-13T14:21:03.803Z","updated_at":"2025-04-11T16:40:37.450Z","avatar_url":"https://github.com/ahuang11.png","language":"Python","readme":"# 🌈 StreamJoy 😊\n\n---\n\n[![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)\n\n[![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)\n\n---\n\n## 🔥 Enjoy animating!\n\nStreamjoy turns your images into animations using sensible defaults for fun, hassle-free creation.\n\nIt cuts down the boilerplate and time to work on animations, and it's simple to start with just a few lines of code.\n\nInstall it with just pip to start, blazingly fast!\n\n```python\npip install streamjoy\n```\n\n\u003cimg src=\"https://github.com/ahuang11/streamjoy/assets/15331990/7c5db7fe-498d-4282-b082-d7f8b36eb915\" width=\"500\"\u003e\n\nOr, try out a basic web app version here:\n\nhttps://huggingface.co/spaces/ahuang11/streamjoy\n\n\u003cimg src=\"https://github.com/ahuang11/streamjoy/assets/15331990/b2e62e5a-b6ba-48a5-863f-6a8c5d4c2887\" width=\"500\"\u003e\n\n## 🛠️ Built-in features\n\n- 🌐 Animate from URLs, files, and datasets\n- 🎨 Render images with default or custom renderers\n- 🎬 Provide context with a short intro splash\n- ⏸ Add pauses at the beginning, end, or between frames\n- ⚡ Execute read, render, and write in parallel\n- 🔗 Connect multiple animations together\n\n## 🚀 Quick start\n\n### 🐤 Absolute basics\n\nStream from a list of images--local files work too!\n\n```python\nfrom streamjoy import stream\n\nif __name__ == \"__main__\":\n    URL_FMT = \"https://www.goes.noaa.gov/dimg/jma/fd/vis/{i}.gif\"\n    resources = [URL_FMT.format(i=i) for i in range(1, 11)]\n    stream(resources, uri=\"goes.gif\")  # .gif, .mp4, and .html supported\n```\n\n\u003cimg src=\"https://github.com/ahuang11/streamjoy/assets/15331990/190ab753-00cf-4a0d-b8be-8a0b9b9e4443\" width=\"500\" height=\"500\"\u003e\n\n### 💅 Polish up\n\nSpecify a few more keywords to:\n\n1. add an intro title and subtitle\n2. adjust the pauses\n3. optimize the GIF thru pygifsicle\n\n```python\nfrom streamjoy import stream\n\nif __name__ == \"__main__\":\n    URL_FMT = \"https://www.goes.noaa.gov/dimg/jma/fd/vis/{i}.gif\"\n    resources = [URL_FMT.format(i=i) for i in range(1, 11)]\n    himawari_stream = stream(\n        resources,\n        uri=\"goes_custom.gif\",\n        intro_title=\"Himawari Visible\",\n        intro_subtitle=\"10 Hours Loop\",\n        intro_pause=1,\n        ending_pause=1,\n        optimize=True,\n    )\n```\n\n\u003cimg src=\"https://github.com/ahuang11/streamjoy/assets/15331990/f69eb289-8074-4b49-9d9e-26f2c47c1a51\" width=\"500\" height=\"500\"\u003e\n\n### 👀 Preview inputs\n\nIf you'd like to preview the `repr` before writing, drop `uri`.\n\nOutput:\n```yaml\n\u003cAnyStream\u003e\n---\nOutput:\n  max_frames: 50\n  fps: 10\n  display: True\n  scratch_dir: streamjoy_scratch\n  in_memory: False\n---\nIntro:\n  intro_title: Himawari Visible\n  intro_subtitle: 10 Hours Loop\n  intro_watermark: made with streamjoy\n  intro_pause: 1\n  intro_background: black\n---\nClient:\n  batch_size: 10\n  processes: True\n  threads_per_worker: None\n---\nResources: (10 frames to stream)\n  https://www.goes.noaa.gov/dimg/jma/fd/vis/1.gif\n  ...\n  https://www.goes.noaa.gov/dimg/jma/fd/vis/10.gif\n---\n```\n\nThen, when ready, call the `write` method to save the animation!\n\n```python\nhimawari_stream.write()\n```\n\n### 🖇️ Connect streams\n\nConnect multiple streams together to provide further context.\n\n```python\nfrom streamjoy import stream, connect\n\nURL_FMTS = {\n    \"visible\": \"https://www.goes.noaa.gov/dimg/jma/fd/vis/{i}.gif\",\n    \"infrared\": \"https://www.goes.noaa.gov/dimg/jma/fd/rbtop/{i}.gif\",\n}\n\nif __name__ == \"__main__\":\n    visible_stream = stream(\n        [URL_FMTS[\"visible\"].format(i=i) for i in range(1, 11)],\n        intro_title=\"Himawari Visible\",\n        intro_subtitle=\"10 Hours Loop\",\n    )\n    infrared_stream = stream(\n        [URL_FMTS[\"infrared\"].format(i=i) for i in range(1, 11)],\n        intro_title=\"Himawari Infrared\",\n        intro_subtitle=\"10 Hours Loop\",\n    )\n    connect([visible_stream, infrared_stream], uri=\"goes_connected.gif\")\n```\n\n\u003cimg src=\"https://github.com/ahuang11/streamjoy/assets/15331990/5f6e0435-f2c2-4c3e-bcf9-4c84d4d060e9\" width=\"500\" height=\"500\"\u003e\n\n### 📷 Render datasets\n\nYou can also render images directly from datasets, either through a custom renderer or a built-in one, and they'll also run in parallel!\n\nThe following example requires xarray, cartopy, matplotlib, and netcdf4.\n\n```bash\npip install xarray cartopy matplotlib netcdf4\n```\n\n```python\nimport numpy as np\nimport cartopy.crs as ccrs\nimport matplotlib.pyplot as plt\nfrom streamjoy import stream, wrap_matplotlib\n\n@wrap_matplotlib()\ndef plot(da, central_longitude, **plot_kwargs):\n    time = da[\"time\"].dt.strftime(\"%b %d %Y\").values.item()\n    projection = ccrs.Orthographic(central_longitude=central_longitude)\n    subplot_kw = dict(projection=projection, facecolor=\"gray\")\n    fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=subplot_kw)\n    im = da.plot(ax=ax, transform=ccrs.PlateCarree(), add_colorbar=False, **plot_kwargs)\n    ax.set_title(f\"Sea Surface Temperature Anomaly\\n{time}\", loc=\"left\", transform=ax.transAxes)\n    ax.set_title(\"Source: NOAA OISST v2.1\", loc=\"right\", size=5, y=-0.01)\n    ax.set_title(\"\", loc=\"center\")  # suppress default title\n    plt.colorbar(im, ax=ax, label=\"°C\", shrink=0.8)\n    return fig\n\nif __name__ == \"__main__\":\n    url = (\n      \"https://www.ncei.noaa.gov/data/sea-surface-temperature-\"\n      \"optimum-interpolation/v2.1/access/avhrr/201008/\"\n    )\n    pattern = \"oisst-avhrr-v02r01.*.nc\"\n    stream(\n        url,\n        uri=\"oisst.gif\",\n        pattern=pattern,  # GifStream.from_url kwargs\n        max_files=30,\n        renderer=plot,  # renderer related kwargs\n        renderer_iterables=[np.linspace(-140, -150, 30)],  # iterables; central longitude per frame (30 frames)\n        renderer_kwargs=dict(cmap=\"RdBu_r\", vmin=-5, vmax=5),  # renderer kwargs\n        # cmap=\"RdBu_r\", # renderer_kwargs can also be propagated for convenience\n        # vmin=-5,\n        # vmax=5,\n    )\n```\n\n\u003cimg src=\"https://github.com/ahuang11/streamjoy/assets/15331990/3db0ae48-d7d5-4e00-a4a4-50bbe4bb3d19\" width=\"500\" height=\"500\"\u003e\n\nCheck 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/))\n\n---\n\n❤️ Made with considerable passion.\n\n🌟 Appreciate the project? Consider giving a star!\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahuang11%2Fstreamjoy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fahuang11%2Fstreamjoy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahuang11%2Fstreamjoy/lists"}