https://github.com/sciqlop/sciqlopplots
https://github.com/sciqlop/sciqlopplots
cpp17 modern-cpp plot plotting qcustomplot qt qt5 sciqlop
Last synced: 26 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/sciqlop/sciqlopplots
- Owner: SciQLop
- License: other
- Created: 2020-05-07T23:05:43.000Z (about 6 years ago)
- Default Branch: main
- Last Pushed: 2024-08-21T10:33:27.000Z (almost 2 years ago)
- Last Synced: 2025-01-31T03:33:01.885Z (over 1 year ago)
- Topics: cpp17, modern-cpp, plot, plotting, qcustomplot, qt, qt5, sciqlop
- Language: C++
- Size: 1.08 MB
- Stars: 1
- Watchers: 3
- Forks: 2
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: COPYING
Awesome Lists containing this project
README
[](https://www.gnu.org/licenses/gpl-3.0)
[]()
[](https://pypi.python.org/pypi/sciqlopplots)
[](https://codecov.io/gh/SciQLop/SciQLopPlots/branch/main)
# SciQLopPlots
A 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.
## Features
- **Async resampling** — render millions of points smoothly; data is downsampled in background threads via [NeoQCP](https://github.com/SciQLop/NeoQCP) pipelines
- **Multiple plot types** — time series (line graphs), spectrograms (color maps), 2D histograms, parametric curves, N-D projection curves, waterfall plots
- **Interactive** — pan, zoom, data-driven callbacks, vertical/horizontal/rectangular spans, tracers, straight lines, text, shapes, pixmaps
- **Multi-plot panels** — synchronized axes, aligned margins, drag-and-drop from product trees
- **Reactive pipelines** — connect plot properties with `>>` to build live data flows
- **Export** — PDF (vector), PNG, JPG, BMP for both individual plots and panels
- **Busy indicator** — visual feedback when data is loading or being processed
- **Runtime inspector** — tree model/view for inspecting and editing plot properties
- **Cross-platform** — Linux, macOS, Windows
## Architecture
```mermaid
graph TD
subgraph Python["Python Layer"]
PY[SciQLopPlots package]
SB[Shiboken6 bindings]
end
subgraph Plots["Plot Hierarchy"]
PI[SciQLopPlotInterface
QFrame]
SP[SciQLopPlot]
TSP[SciQLopTimeSeriesPlot]
NDP[SciQLopNDProjectionPlot]
end
subgraph Plotables["Plotables"]
PTI[SciQLopPlottableInterface
QObject]
GI[SciQLopGraphInterface]
CMI[SciQLopColorMapInterface]
LG[SciQLopLineGraph]
SLG[SciQLopSingleLineGraph]
CRV[SciQLopCurve]
WF[SciQLopWaterfallGraph]
NDC[SciQLopNDProjectionCurves]
CMB[SciQLopColorMapBase]
CM[SciQLopColorMap]
H2D[SciQLopHistogram2D]
end
subgraph Items["Overlay Items"]
VS[VerticalSpan]
HS[HorizontalSpan]
RS[RectangularSpan]
TR[Tracer]
SL[StraightLine]
end
subgraph MultiPlot["Multi-Plot"]
PPI[SciQLopPlotPanelInterface]
MPP[SciQLopMultiPlotPanel]
AX[AxisSynchronizer]
VA[VPlotsAlign]
end
PY --> SB --> PI
PI --> SP
PI --> NDP
SP --> TSP
PTI --> GI
PTI --> CMI
GI --> LG
GI --> SLG
GI --> CRV
GI --> WF
GI --> NDC
CMI --> CMB
CMB --> CM
CMB --> H2D
PPI --> MPP
MPP --> AX
MPP --> VA
SP -.->|contains| PTI
SP -.->|contains| Items
MPP -.->|contains| SP
```
### Data flow
```mermaid
sequenceDiagram
participant User
participant Plot as SciQLopPlot
participant Resampler as Resampler
(worker thread)
participant NeoQCP as NeoQCP
User->>Plot: pan / zoom
Plot->>Resampler: new visible range
Resampler->>Resampler: downsample data
Resampler->>NeoQCP: resampled points
NeoQCP->>Plot: render
```
For 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.
## Quick start
```bash
pip install SciQLopPlots
```
```python
import numpy as np
from PySide6.QtWidgets import QApplication
from SciQLopPlots import SciQLopPlot
app = QApplication([])
plot = SciQLopPlot()
# Static data
x = np.arange(0, 1000, dtype=np.float64)
y = np.sin(x / 100) * np.cos(x / 10)
plot.plot(x, y, labels=["signal"])
# Data callback (called on pan/zoom with visible range)
def get_data(start, stop):
x = np.arange(start, stop, dtype=np.float64)
y = np.column_stack([np.sin(x / 100), np.cos(x / 100)])
return x, y
plot.plot(get_data, labels=["sin", "cos"])
plot.show()
app.exec()
```
### Reactive pipelines
Connect plot properties with the `>>` operator to build live data pipelines:
```python
from SciQLopPlots import SciQLopPlot
plot = SciQLopPlot()
graph = plot.plot(lambda start, stop: ..., labels=["signal"])
# Axis range changes automatically feed a transform, which pushes data to the graph
plot.x_axis.on.range >> get_data >> graph.on.data
# Direct property forwarding (no transform)
span.on.range >> plot.x_axis.on.range
# Chain multiple steps
source.on.range >> transform >> target.on.data
```
Run the gallery for a full feature showcase:
```bash
python tests/manual-tests/gallery.py
```
## Building from source
Requires Qt6, PySide6 == 6.11.0, a C++20 compiler, and Meson.
```bash
# Development build (recommended — plain `debug` disables optimizations
# and makes the resampling pipelines noticeably sluggish)
meson setup build --buildtype=debugoptimized
meson compile -C build
# Install as editable Python package
pip install -e . --no-build-isolation
```
### Build options
| Option | Type | Default | Description |
|---|---|---|---|
| `trace_refcount` | bool | false | Enable reference count tracing |
| `tracy_enable` | bool | false | Enable Tracy profiling |
| `with_opengl` | bool | true | Enable OpenGL support |
## Contributing
Fork the repository, make your changes and submit a pull request.
Bug reports and feature requests are welcome.
## Credits
Development is supported by [CDPP](http://www.cdpp.eu/).
We acknowledge support from [Plas@Par](https://www.plasapar.sorbonne-universite.fr).
## Thanks
- [PySide6](https://doc.qt.io/qtforpython-6/index.html) — Qt bindings and Shiboken6 binding generator
- [NeoQCP](https://github.com/SciQLop/NeoQCP) — fork of [QCustomPlot](https://www.qcustomplot.com/) with async pipelines, multi-dtype support, and QRhi rendering