{"id":15044961,"url":"https://github.com/sciqlop/sciqlopplots","last_synced_at":"2026-05-06T23:02:37.624Z","repository":{"id":62230012,"uuid":"262176797","full_name":"SciQLop/SciQLopPlots","owner":"SciQLop","description":null,"archived":false,"fork":false,"pushed_at":"2024-08-21T10:33:27.000Z","size":1133,"stargazers_count":1,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-01-31T03:33:01.885Z","etag":null,"topics":["cpp17","modern-cpp","plot","plotting","qcustomplot","qt","qt5","sciqlop"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SciQLop.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","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":"2020-05-07T23:05:43.000Z","updated_at":"2024-08-17T16:24:10.000Z","dependencies_parsed_at":"2023-02-14T17:46:29.686Z","dependency_job_id":"e833405f-56d4-4c11-a59c-8cf8e81a3505","html_url":"https://github.com/SciQLop/SciQLopPlots","commit_stats":{"total_commits":181,"total_committers":2,"mean_commits":90.5,"dds":"0.027624309392265234","last_synced_commit":"9b97578aea03ad87a1c73cd10fd8624730d00285"},"previous_names":[],"tags_count":47,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SciQLop%2FSciQLopPlots","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SciQLop%2FSciQLopPlots/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SciQLop%2FSciQLopPlots/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SciQLop%2FSciQLopPlots/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SciQLop","download_url":"https://codeload.github.com/SciQLop/SciQLopPlots/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238008507,"owners_count":19401263,"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":["cpp17","modern-cpp","plot","plotting","qcustomplot","qt","qt5","sciqlop"],"created_at":"2024-09-24T20:51:17.194Z","updated_at":"2026-05-03T20:09:38.091Z","avatar_url":"https://github.com/SciQLop.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)\n[![C++20](https://img.shields.io/badge/Language-C++20-blue.svg)]()\n[![PyPi](https://img.shields.io/pypi/v/sciqlopplots.svg)](https://pypi.python.org/pypi/sciqlopplots)\n[![Coverage](https://codecov.io/gh/SciQLop/SciQLopPlots/coverage.svg?branch=main)](https://codecov.io/gh/SciQLop/SciQLopPlots/branch/main)\n\n# SciQLopPlots\n\nA high-performance scientific plotting library built on C++20/Qt6 with Python bindings via Shiboken6 (PySide6). Designed for the [SciQLop](https://github.com/SciQLop/SciQLop) data analysis platform but usable standalone.\n\n## Features\n\n- **Async resampling** — render millions of points smoothly; data is downsampled in background threads via [NeoQCP](https://github.com/SciQLop/NeoQCP) pipelines\n- **Multiple plot types** — time series (line graphs), spectrograms (color maps), 2D histograms, parametric curves, N-D projection curves, waterfall plots\n- **Interactive** — pan, zoom, data-driven callbacks, vertical/horizontal/rectangular spans, tracers, straight lines, text, shapes, pixmaps\n- **Multi-plot panels** — synchronized axes, aligned margins, drag-and-drop from product trees\n- **Reactive pipelines** — connect plot properties with `\u003e\u003e` to build live data flows\n- **Export** — PDF (vector), PNG, JPG, BMP for both individual plots and panels\n- **Busy indicator** — visual feedback when data is loading or being processed\n- **Runtime inspector** — tree model/view for inspecting and editing plot properties\n- **Cross-platform** — Linux, macOS, Windows\n\n## Architecture\n\n```mermaid\ngraph TD\n    subgraph Python[\"Python Layer\"]\n        PY[SciQLopPlots package]\n        SB[Shiboken6 bindings]\n    end\n\n    subgraph Plots[\"Plot Hierarchy\"]\n        PI[SciQLopPlotInterface\u003cbr/\u003e\u003ci\u003eQFrame\u003c/i\u003e]\n        SP[SciQLopPlot]\n        TSP[SciQLopTimeSeriesPlot]\n        NDP[SciQLopNDProjectionPlot]\n    end\n\n    subgraph Plotables[\"Plotables\"]\n        PTI[SciQLopPlottableInterface\u003cbr/\u003e\u003ci\u003eQObject\u003c/i\u003e]\n        GI[SciQLopGraphInterface]\n        CMI[SciQLopColorMapInterface]\n        LG[SciQLopLineGraph]\n        SLG[SciQLopSingleLineGraph]\n        CRV[SciQLopCurve]\n        WF[SciQLopWaterfallGraph]\n        NDC[SciQLopNDProjectionCurves]\n        CMB[SciQLopColorMapBase]\n        CM[SciQLopColorMap]\n        H2D[SciQLopHistogram2D]\n    end\n\n    subgraph Items[\"Overlay Items\"]\n        VS[VerticalSpan]\n        HS[HorizontalSpan]\n        RS[RectangularSpan]\n        TR[Tracer]\n        SL[StraightLine]\n    end\n\n    subgraph MultiPlot[\"Multi-Plot\"]\n        PPI[SciQLopPlotPanelInterface]\n        MPP[SciQLopMultiPlotPanel]\n        AX[AxisSynchronizer]\n        VA[VPlotsAlign]\n    end\n\n    PY --\u003e SB --\u003e PI\n\n    PI --\u003e SP\n    PI --\u003e NDP\n    SP --\u003e TSP\n\n    PTI --\u003e GI\n    PTI --\u003e CMI\n    GI --\u003e LG\n    GI --\u003e SLG\n    GI --\u003e CRV\n    GI --\u003e WF\n    GI --\u003e NDC\n    CMI --\u003e CMB\n    CMB --\u003e CM\n    CMB --\u003e H2D\n\n    PPI --\u003e MPP\n    MPP --\u003e AX\n    MPP --\u003e VA\n\n    SP -.-\u003e|contains| PTI\n    SP -.-\u003e|contains| Items\n    MPP -.-\u003e|contains| SP\n```\n\n### Data flow\n\n```mermaid\nsequenceDiagram\n    participant User\n    participant Plot as SciQLopPlot\n    participant Resampler as Resampler\u003cbr/\u003e(worker thread)\n    participant NeoQCP as NeoQCP\n\n    User-\u003e\u003ePlot: pan / zoom\n    Plot-\u003e\u003eResampler: new visible range\n    Resampler-\u003e\u003eResampler: downsample data\n    Resampler-\u003e\u003eNeoQCP: resampled points\n    NeoQCP-\u003e\u003ePlot: render\n```\n\nFor callback-driven data, the plot invokes a Python callable with `(start, stop)` on range change, and the returned arrays flow through the same resampling pipeline.\n\n## Quick start\n\n```bash\npip install SciQLopPlots\n```\n\n```python\nimport numpy as np\nfrom PySide6.QtWidgets import QApplication\nfrom SciQLopPlots import SciQLopPlot\n\napp = QApplication([])\nplot = SciQLopPlot()\n\n# Static data\nx = np.arange(0, 1000, dtype=np.float64)\ny = np.sin(x / 100) * np.cos(x / 10)\nplot.plot(x, y, labels=[\"signal\"])\n\n# Data callback (called on pan/zoom with visible range)\ndef get_data(start, stop):\n    x = np.arange(start, stop, dtype=np.float64)\n    y = np.column_stack([np.sin(x / 100), np.cos(x / 100)])\n    return x, y\n\nplot.plot(get_data, labels=[\"sin\", \"cos\"])\n\nplot.show()\napp.exec()\n```\n\n### Reactive pipelines\n\nConnect plot properties with the `\u003e\u003e` operator to build live data pipelines:\n\n```python\nfrom SciQLopPlots import SciQLopPlot\n\nplot = SciQLopPlot()\ngraph = plot.plot(lambda start, stop: ..., labels=[\"signal\"])\n\n# Axis range changes automatically feed a transform, which pushes data to the graph\nplot.x_axis.on.range \u003e\u003e get_data \u003e\u003e graph.on.data\n\n# Direct property forwarding (no transform)\nspan.on.range \u003e\u003e plot.x_axis.on.range\n\n# Chain multiple steps\nsource.on.range \u003e\u003e transform \u003e\u003e target.on.data\n```\n\nRun the gallery for a full feature showcase:\n\n```bash\npython tests/manual-tests/gallery.py\n```\n\n## Building from source\n\nRequires Qt6, PySide6 == 6.11.0, a C++20 compiler, and Meson.\n\n```bash\n# Development build (recommended — plain `debug` disables optimizations\n# and makes the resampling pipelines noticeably sluggish)\nmeson setup build --buildtype=debugoptimized\nmeson compile -C build\n\n# Install as editable Python package\npip install -e . --no-build-isolation\n```\n\n### Build options\n\n| Option | Type | Default | Description |\n|---|---|---|---|\n| `trace_refcount` | bool | false | Enable reference count tracing |\n| `tracy_enable` | bool | false | Enable Tracy profiling |\n| `with_opengl` | bool | true | Enable OpenGL support |\n\n## Contributing\n\nFork the repository, make your changes and submit a pull request.\nBug reports and feature requests are welcome.\n\n## Credits\n\nDevelopment is supported by [CDPP](http://www.cdpp.eu/).\nWe acknowledge support from [Plas@Par](https://www.plasapar.sorbonne-universite.fr).\n\n## Thanks\n\n- [PySide6](https://doc.qt.io/qtforpython-6/index.html) — Qt bindings and Shiboken6 binding generator\n- [NeoQCP](https://github.com/SciQLop/NeoQCP) — fork of [QCustomPlot](https://www.qcustomplot.com/) with async pipelines, multi-dtype support, and QRhi rendering\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsciqlop%2Fsciqlopplots","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsciqlop%2Fsciqlopplots","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsciqlop%2Fsciqlopplots/lists"}