{"id":21890628,"url":"https://github.com/grafana-toolbox/grafanimate","last_synced_at":"2025-04-15T13:39:25.814Z","repository":{"id":33853037,"uuid":"163039984","full_name":"grafana-toolbox/grafanimate","owner":"grafana-toolbox","description":"Animate timeseries data with Grafana.","archived":false,"fork":false,"pushed_at":"2024-04-21T15:25:19.000Z","size":178,"stargazers_count":41,"open_issues_count":9,"forks_count":5,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-05-15T13:21:36.438Z","etag":null,"topics":["animation","animation-engine","animation-framework","animation-library","datavis","datavisualization","dataviz","grafana","grafana-client","grafana-dashboard","kotori-daq","time-series","timeseries","timespan","visualisation","visualization"],"latest_commit_sha":null,"homepage":"https://community.panodata.org/t/grafanimate/205","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/grafana-toolbox.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES.rst","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-12-25T02:54:08.000Z","updated_at":"2024-05-15T13:21:42.043Z","dependencies_parsed_at":"2024-04-13T18:41:24.624Z","dependency_job_id":"eb9f1b05-8828-4be0-a20d-f48f4eea8203","html_url":"https://github.com/grafana-toolbox/grafanimate","commit_stats":{"total_commits":139,"total_committers":5,"mean_commits":27.8,"dds":0.5035971223021583,"last_synced_commit":"1679701a4fa02c2db9e79ad0eec56f9221abbd8f"},"previous_names":["grafana-toolbox/grafanimate","panodata/grafanimate"],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafana-toolbox%2Fgrafanimate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafana-toolbox%2Fgrafanimate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafana-toolbox%2Fgrafanimate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grafana-toolbox%2Fgrafanimate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/grafana-toolbox","download_url":"https://codeload.github.com/grafana-toolbox/grafanimate/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249081516,"owners_count":21209712,"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":["animation","animation-engine","animation-framework","animation-library","datavis","datavisualization","dataviz","grafana","grafana-client","grafana-dashboard","kotori-daq","time-series","timeseries","timespan","visualisation","visualization"],"created_at":"2024-11-28T12:16:10.136Z","updated_at":"2025-04-15T13:39:25.807Z","avatar_url":"https://github.com/grafana-toolbox.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":".. image:: https://img.shields.io/pypi/v/grafanimate.svg\n    :target: https://pypi.org/project/grafanimate/\n\n.. image:: https://img.shields.io/pypi/status/grafanimate.svg\n    :target: https://pypi.org/project/grafanimate/\n\n.. image:: https://codecov.io/gh/grafana-toolbox/grafanimate/branch/main/graph/badge.svg\n    :target: https://codecov.io/gh/grafana-toolbox/grafanimate\n    :alt: Code coverage\n\n.. image:: https://img.shields.io/pypi/l/grafanimate.svg\n    :alt: License\n    :target: https://pypi.org/project/grafanimate/\n\n.. image:: https://img.shields.io/pypi/dm/grafanimate.svg\n    :target: https://pypi.org/project/grafanimate/\n\n.. image:: https://img.shields.io/pypi/pyversions/grafanimate.svg\n    :target: https://pypi.org/project/grafanimate/\n\n.. image:: https://img.shields.io/badge/Grafana-10.x%20--%2011.x-blue.svg\n    :target: https://github.com/grafana/grafana\n    :alt: Supported Grafana versions\n\n|\n\n###########\ngrafanimate\n###########\n\nAnimate timeseries data with Grafana.\n\n\n*****\nAbout\n*****\n\n``grafanimate`` captures screenshots while animating a Grafana dashboard by\nmanipulating its `time range control`_, i.e. navigating through time. The\nresult can be rendered as a sequence of png images, an animated gif file,\nand as a video file.\n\n.. attention::\n\n    This program can put significant load on your Grafana instance\n    and the underlying database machinery. Handle with care!\n\n\n*****\nSetup\n*****\n\nPrerequisites\n=============\n\nThis program uses the fine FFmpeg_ program for doing the heavy lifting within\nin its postprocessing subsystem.\n\n\ngrafanimate\n===========\n\n.. code:: sh\n\n    pip install grafanimate\n\n\n.. note::\n\n    We absolutely recommend installing this program into a Python virtualenv::\n\n        python3 -m venv .venv\n        source .venv/bin/activate\n        pip install grafanimate\n\n\n*****\nUsage\n*****\n\nIntroduction\n============\n\n``grafanimate`` works by operating on animations defined within description\nfiles, written in Python. In cinematography jargon, this is called \"exposure\nsheet\", or \"dope sheet\".\n\n    An exposure sheet (also known variously as \"dope sheet\", \"camera\n    instruction sheet\", or \"X-sheet\") is a sheet of paper used primarily in\n    traditional animation to mark out the timing of various actions and\n    dialogue.\n\n``grafanimate`` offers convenient data types, ``AnimationScenario`` and\n``AnimationSequence``, for outlining an animation scenario made of multiple\nsequences.\n\nPlease have a look at the `scenarios.py`_ file for a full example containing\nmultiple scenarios.\n\nSynopsis\n========\n\nA scenario definition:\n\n.. code:: python\n\n    AnimationScenario(\n        grafana_url=\"https://play.grafana.org/\",\n        dashboard_uid=\"000000012\",\n        sequences=[\n            AnimationSequence(\n                start=\"2021-11-15T02:12:05Z\",\n                stop=\"2021-11-15T02:37:36Z\",\n                every=\"5min\",\n                mode=SequencingMode.CUMULATIVE,\n            ),\n        ],\n    )\n\n\nIn order to run a built-in scenario, invoke:\n\n.. code:: sh\n\n    grafanimate --scenario=playdemo --output=./animations\n\nTo use the headless mode which renders all panels on a dashboard and use panel events instead of waiting a fixed duration run\n\n.. code:: sh\n\n    grafanimate --scenario=playdemo --output=./animations--headless --use-panel-events\n\nDetails\n=======\n\n``grafanimate`` also supports relative timestamps, based on the fine\n`pytimeparse2`_ library.\n\n- Within ``every``, you will express a duration.\n\nHelp\n====\n\nFor getting a detailed and descriptive overview about all available command\nline options, please invoke:\n\n.. code:: sh\n\n    grafanimate --help\n\nConfiguration\n=============\n\nFirefox Location\n----------------\ngrafanimate will discover a Firefox installation on your system path.\nIf you need to configure a specific installation location, use the\nenvironment variable ``FIREFOX_BIN`` to point to the Firefox executable\non your system.\n\nExamples\n========\n\nExamples for scenario mode. Script your animations in file ``scenarios.py`` or\nany other Python module or file.\n\n.. code:: sh\n\n    # Use freely accessible `play.grafana.org` for demo purposes.\n    grafanimate --scenario=playdemo --output=./animations\n\n    # Example for generating Luftdaten.info graph \u0026 map.\n    export GRAFANIMATE_OUTPUT=./animations\n    grafanimate --grafana-url=http://localhost:3000/ --dashboard-uid=1aOmc1sik --scenario=ldi_all\n\n    # Use more parameters to control the rendering process.\n    grafanimate --grafana-url=http://localhost:3000/ --dashboard-uid=acUXbj_mz --scenario=ir_sensor_svg_pixmap \\\n        --header-layout=studio --datetime-format=human-time --panel-id=6\n\n\n*******************\nUsage in Containers\n*******************\n\nYou can use ``grafanimate`` with Docker and Podman. An OCI image is published\nto ``ghcr.io/grafana-toolbox/grafanimate``.\n\n.. code:: sh\n\n    docker run --rm -it --volume=$(PWD)/animations:/animations ghcr.io/grafana-toolbox/grafanimate \\\n        --header-layout=no-chrome \\\n        --video-fps=30 --video-framerate=30 \\\n        --scenario=playdemo --output=./animations\n\n\n*******\nGallery\n*******\n\n**Composition**: `The Hiveeyes Project`_. Developing a flexible beehive monitoring infrastructure.\nClicking on an image will take you to the animated version.\n\n.. _The Hiveeyes Project: https://hiveeyes.org/\n\n\nluftdaten.info coverage\n=======================\n.. figure:: https://ptrace.hiveeyes.org/2018-12-28_luftdaten-info-coverage.gif\n    :target: https://ptrace.hiveeyes.org/2018-12-28_luftdaten-info-coverage.mp4\n    :width: 480px\n    :height: 306px\n    :scale: 125%\n\n    Coverage of luftdaten.info sensors starting October 2015 across Europe.\n\n- **Data source**: `luftdaten.info`_ (LDI)\n- **Production**:  `Luftdatenpumpe`_, `LDI data plane v2`_, daily.\n- **Development**: `Erneuerung der Luftdatenpumpe`_. All contributions welcome.\n\n\nFine dust pollution on New Year's Eve\n=====================================\n.. figure:: https://ptrace.hiveeyes.org/2019-02-04_M0h7br_ik_2019-01-01T00-15-00.png\n    :target: https://ptrace.hiveeyes.org/2019-02-03_particulates-on-new-year-s-eve.mp4\n    :width: 1290px\n    :height: 824px\n    :scale: 50%\n\n    `Animation of fine dust pollution on New Year's Eve 2018 across Europe \u003chttps://community.hiveeyes.org/t/animation-der-feinstaubbelastung-an-silvester-2018-mit-grafanimate/1472\u003e`_.\n\n- **Data source**: `luftdaten.info`_ (LDI)\n- **Production**:  `Luftdatenpumpe`_, `LDI data plane v2`_, historical.\n- **Development**: `Erneuerung der Luftdatenpumpe`_. All contributions welcome.\n\n.. _luftdaten.info: http://luftdaten.info/\n.. _Luftdatenpumpe: https://github.com/hiveeyes/luftdatenpumpe\n.. _Erneuerung der Luftdatenpumpe: https://community.hiveeyes.org/t/erneuerung-der-luftdatenpumpe/1199\n.. _LDI data plane v2: https://community.hiveeyes.org/t/ldi-data-plane-v2/1412\n\n\nDWD CDC\n=======\n.. figure:: https://ptrace.hiveeyes.org/2019-02-04_DLOlE_Rmz_2018-03-10T13-00-00.png\n    :target: https://ptrace.hiveeyes.org/2018-12-28_wetter-dwd-temperatur-sonne-niederschlag-karten-cdc.mp4\n    :width: 1428px\n    :height: 829px\n    :scale: 50%\n\n    `Short weather film about temperature, sun and precipitation based on DWD/CDC data in March 2018 \u003chttps://community.hiveeyes.org/t/kurzer-wetterfilm-uber-temperatur-sonne-und-niederschlag-auf-basis-der-dwd-cdc-daten-im-marz-2018/1475\u003e`_.\n\n- **Data source**: `DWD Open Data`_ (DWD)\n- **Production**:  `DWD Climate Data Center (CDC), 10m-Werte: Aktuelle Lufttemperaturen, Sonnenscheindauer \u0026 Niederschlag \u003chttps://weather.hiveeyes.org/grafana/d/DLOlE_Rmz/temperatur-sonne-and-niederschlag-karten-cdc\u003e`_\n- **Development**: \u003cwork in progress\u003e\n\n.. _DWD Open Data: https://opendata.dwd.de/\n\n\nIR-Sensor SVG-Pixmap\n====================\n.. figure:: https://ptrace.hiveeyes.org/2019-02-04_acUXbj_mz_2018-08-14T03-16-12.png\n    :target: https://ptrace.hiveeyes.org/2019-02-04_ir-sensor-svg-pixmap.mp4\n    :width: 666px\n    :height: 700px\n    :scale: 50%\n\n    IR-Sensor SVG-Pixmap displaying temperature changes inside a beehive.\n\n- **Data source**: `Clemens Gruber`_ (CG)\n- **Development**: `How to Visualize 2-Dimensional Temperature Data in Grafana \u003chttps://community.hiveeyes.org/t/how-to-visualize-2-dimensional-temperature-data-in-grafana/974/15\u003e`_\n\n.. _Clemens Gruber: https://community.hiveeyes.org/u/clemens\n\n\n\n**********************\nBackground and details\n**********************\n\nIntroduction\n============\nAnimating things in Grafana_ across the time-axis in the spirit\nof the `GeoLoop Panel Plugin`_ hasn't been unlocked for Grafana\nin a more general way yet. Challenge accepted!\n\nTime warp\n=========\nAt this programs' core is the code to `set time range in Grafana`_:\n\n.. code:: javascript\n\n    __grafanaSceneContext.state.$timeRange.setState({ from: from, to: to});\n    __grafanaSceneContext.state.$timeRange.onRefresh();\n\nRendering engine\n================\nTurtles all the way up, the main rendering work horse is a Firefox Browser\nautomated through `Marionette Python Client`_ fame:\n\n    The Marionette Python client library allows you to remotely control\n    a Gecko-based browser or device which is running a Marionette server.\n\nOutlook\n=======\nNeither Playlists_ nor `Scripted Dashboards`_ (now deprecated) offer these\nthings to the user, but this program can be combined with both in order\nto implement more complex animations on top of Grafana.\n\n\n----\n\n***********\nDevelopment\n***********\n\n.. code:: sh\n\n    # Acquire sources.\n    git clone https://github.com/grafana-toolbox/grafanimate\n    cd grafanimate\n\n    # Create and activate virtualenv.\n    uv venv\n    source .venv/bin/activate\n\n    # Install package in \"editable\" mode.\n    uv pip install --editable='.[develop,test]'\n\n    # Run linters and software tests.\n    poe check\n\n\n*******************\nProject information\n*******************\n\nThe code lives on `GitHub \u003chttps://github.com/grafana-toolbox/grafanimate\u003e`_ and\nthe Python package is published to `PyPI \u003chttps://pypi.org/project/grafanimate/\u003e`_.\n\n\nContributing\n============\nWe are always happy to receive code contributions, ideas, suggestions\nand problem reports from the community.\nSpend some time taking a look around, locate a bug, design issue or\nspelling mistake and then send us a pull request or create an issue.\nYou can also `discuss grafanimate`_ on our forum, you are welcome to join.\n\n\nAcknowledgements\n================\nThanks to all the contributors who helped to co-create and conceive this\nprogram in one way or another. You know who you are.\n\nAlso thanks to all the people working on Python, Grafana, Firefox, FFmpeg,\nand the countless other software components this program is based upon.\n\n\nLicense\n=======\n``grafanimate`` is licensed under the terms of the GNU AGPL v3 license.\n\n\n\n.. _discuss grafanimate: https://community.panodata.org/t/grafanimate/205\n.. _FFmpeg: https://ffmpeg.org/\n.. _GeoLoop Panel Plugin: https://grafana.com/plugins/citilogics-geoloop-panel\n.. _Grafana: https://grafana.com/\n.. _Marionette Python Client: https://marionette-client.readthedocs.io/\n.. _Playlists: http://docs.grafana.org/reference/playlist/\n.. _pytimeparse2: https://github.com/onegreyonewhite/pytimeparse2\n.. _scenarios.py: https://github.com/grafana-toolbox/grafanimate/blob/main/grafanimate/scenarios.py\n.. _Scripted Dashboards: http://docs.grafana.org/reference/scripting/\n.. _set time range in Grafana: https://stackoverflow.com/questions/48264279/how-to-set-time-range-in-grafana-dashboard-from-text-panels/52492205#52492205\n.. _time range control: http://docs.grafana.org/reference/timerange/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrafana-toolbox%2Fgrafanimate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrafana-toolbox%2Fgrafanimate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrafana-toolbox%2Fgrafanimate/lists"}