Metadata-Version: 2.4
Name: pyqtgraph-styler
Version: 0.1.0
Summary: Matplotlib-inspired styles and vector sketch drawing for pyqtgraph
License-Expression: MIT
Keywords: pyqtgraph,matplotlib,styles,xkcd,Qt
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Visualization
Requires-Python: >=3.10
Description-Content-Type: text/x-rst
License-File: LICENSE
License-File: src/pyqtgraph_styler/fonts/OFL.txt
Requires-Dist: pyqtgraph<0.15,>=0.14
Requires-Dist: matplotlib<4,>=3.10
Requires-Dist: numpy>=1.25
Provides-Extra: pyside6
Requires-Dist: PySide6>=6.5; extra == "pyside6"
Provides-Extra: pyqt6
Requires-Dist: PyQt6>=6.5; extra == "pyqt6"
Provides-Extra: dev
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: pytest; extra == "dev"
Dynamic: license-file

pyqtgraph-styler
================

Named Matplotlib-inspired plot styles and vector XKCD drawing for pyqtgraph.
The package styles existing plots. It does not own data loading, calculations,
interaction, axis ranges or application windows.

Installation
------------

Install with one Qt binding::

    python -m pip install "pyqtgraph-styler[pyside6]"

To install from a local checkout, run this from the project folder::

    python -m pip install ".[pyside6]"

Matplotlib is a required dependency. It supplies the style catalogue and its
compiled sketch-path calculation. No Matplotlib GUI backend or pyplot window is
created. The Qt bindings are optional extras because applications often already
have either PySide6 or PyQt6 installed.

One-line application
--------------------

Create the plot normally, then apply a style::

    import numpy as np
    import pyqtgraph as pg
    import pyqtgraph_styler as styler

    app = pg.mkQApp()
    window = pg.PlotWidget()
    window.addLegend()
    x = np.linspace(0, 10, 200)
    window.plot(x, np.sin(x), name="y data")
    window.setLabel("bottom", "x data")
    styler.apply(window, "seaborn-v0_8-whitegrid")
    window.show()
    app.exec()

Use ``styler.available()`` for the catalogue. It contains Matplotlib's public
installed style names plus ``default`` and ``xkcd``: ggplot, bmh, classic,
fivethirtyeight, dark_background, grayscale, Solarize_Light2, tableau-colorblind10,
and the seaborn-v0_8 variants, among others.

Call ``apply`` after adding native curves and legends, and again after adding
new ones. The function deliberately does not hook future events or change global
pyqtgraph defaults. Explicitly restyling a plot changes its curve colours and
widths to the preset. Data and ranges stay unchanged.

Applications which already own series styling can keep those settings::

    appearance = styler.load("ggplot")
    appearance.apply(plot, curves=False, grid=False, fonts=False)
    colour = appearance.colors[series_number % len(appearance.colors)]

``load`` caches immutable presets. The same preset can style several figures;
applying a dark style to one plot does not change another plot.

XKCD drawing
------------

For ordinary ``PlotWidget.plot`` items, this also works::

    styler.apply(window, "xkcd")

The original PlotDataItem, its marker item, data arrays and signals remain in
place. Only its curve child is replaced with a sketch-capable curve. If your
application keeps references to that child, create ``styler.DataItem`` instead.
For directly created PlotCurveItem objects, use ``styler.CurveItem``::

    curve = styler.CurveItem(x, y, sketch=(1, 100, 2))
    plot.addItem(curve)

Normal styles use pyqtgraph's normal curve painter. XKCD converts only the
visible drawing path through Matplotlib's sketch operation; original samples
are untouched. Gaps and step corners remain in the path. The resulting vector
path is cached until data or drawing scale changes. Source data remains suitable
for cursors, calculation and export to a data file. The visible stroke is
intentionally displaced slightly, so use a normal style for precise visual
readings. Curve and frame paths are sketched; scatter symbols, contour polygons,
bar rectangles and text glyphs are not distorted. Text uses Comic Sans MS when
installed; Qt otherwise selects the bundled Comic Neue font. The application
does not choose or install sketch fonts. Area fills retain their original region.

Supported appearance and limits
-------------------------------

Supported: figure/axes backgrounds, text and tick colours, font families,
native grid visibility/colour, per-side frame visibility/colour/width,
automatic curve colour cycles/widths and legend frame/background/text.
The Qt layout and tick locator remain in use. Styles are visual translations,
not pixel-identical Matplotlib output. Backend settings such as Agg chunking,
TeX, path simplification and Matplotlib layout parameters have no corresponding
effect. The ``fast`` preset does not accelerate pyqtgraph.

All style names are available, but not every rcParam is translated. Property
cycles currently use colours; marker/dash cycles are not interpreted. Native
pyqtgraph grid rendering also differs from Matplotlib. Existing application
settings may intentionally override theme defaults, including grid visibility,
font sizes and explicit series colours. Qt widget stylesheets (buttons/docks)
are outside this plot-style package.

Vector export uses Qt's QPainter with QSvgGenerator or QPdfWriter. With the tested Qt version, pyqtgraph 0.14's separate SVGExporter fails on
unstyled plots too; this package does not patch that exporter.

Supported versions: Python 3.10+, pyqtgraph 0.14.x, Matplotlib 3.10+. This first
release is experimental. The curve-child integration is deliberately bounded to
pyqtgraph 0.14 until later versions are tested.

Packaging and release
---------------------

Build and validate locally::

    python -m pip install -e ".[pyside6,dev]"
    python -m pytest
    python -m build
    python -m twine check dist/*

The wheel includes the font and its OFL licence. No resources are downloaded
at runtime. For Nuitka include package data with
``--include-package-data=pyqtgraph_styler``; Matplotlib's own data must also be
included by the build. Test the frozen program on a machine without Python.

Nothing is published by these commands. When a release is approved, uploading
is a separate explicit step with ``python -m twine upload dist/*``. The package
name is not reserved until a successful upload to PyPI.

Maintenance
-----------

``styles.py`` translates appearance. ``sketch.py`` owns the drawing adapter.
``tests`` checks all presets, source-data preservation, independent figures,
sketch gaps, cache invalidation and vector export. ``examples/gallery.py`` is
an interactive visual comparison. Keep rendering and data preparation outside
this package.

Licences
--------

Package code is MIT licensed. Comic Neue is distributed under the SIL Open Font
License included in ``fonts/OFL.txt``. The font comes from
https://github.com/google/fonts/tree/main/ofl/comicneue . Matplotlib and
pyqtgraph are dependencies with their own licences; their source is not copied
into this package. This is an independent project, not an official Matplotlib,
pyqtgraph or XKCD product.

