"""
gleplot - Matplotlib-like plotting library for GLE
A Python library for creating scientific plots using matplotlib-like syntax
that compiles directly to GLE (Graphics Layout Engine) format for publication-
quality vector graphics.
Features
--------
- Matplotlib-compatible API (plot, scatter, bar, fill_between, errorbar)
- Text annotations in data coordinates (text)
- Subplots with flexible grid layouts (subplots, add_subplot)
- Native vector graphics output (PDF, PNG, EPS)
- Inline display in Jupyter notebooks (view)
- Support for line styles, markers, and colors
- Error bars (symmetric, asymmetric, horizontal)
- Logarithmic scales
- Legend and axis labels
- Semantic per-series data file naming (data_name) and figure-level prefixes (data_prefix)
- Direct GLE script generation
Usage
-----
import gleplot as glp
fig = glp.figure(figsize=(8, 6))
ax = fig.add_subplot(111)
ax.plot([1, 2, 3], [1, 4, 9], 'b-', label='quadratic')
ax.scatter([1, 2, 3], [1, 2, 3], color='red', label='points')
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_title('Example Plot')
ax.legend()
fig.savefig('output.pdf') # Saves as PDF
fig.savefig('output.gle') # Saves as GLE script only
fig.view() # Display inline in Jupyter notebook
Classes
-------
Figure
Matplotlib-like figure container
Axes
Matplotlib-like axes for plotting
Functions
---------
figure(figsize=(8, 6), dpi=100)
Create a new figure
"""
__version__ = "2.8.1"
__author__ = "gleplot contributors"
from .figure import Figure
from .axes import Axes, validate_tick_format
from .brokenaxes import BrokenAxes
from .colors import rgb_to_gle, get_color_palette
from .markers import get_gle_marker
from .mathtext import mathtext_to_gle
from .compiler import GLECompiler
from .config import (
GLEStyleConfig,
GLEGraphConfig,
GLEMarkerConfig,
GlobalConfig,
)
# Series data sources: where a series' numbers come from. The scripting API
# always produces InlineData (baked arrays) and never needs these; they are
# the API an embedding application uses to point series at its own tables.
from .sources import (
ColumnRef,
DanglingSourceRef,
DanglingSourceWarning,
DataProvider,
DataSource,
DictDataProvider,
GridRef,
InlineData,
TableData,
)
# Module-level convenience functions (for matplotlib compatibility)
_current_figure = None
def open_gle(path, *, base_dir=None) -> Figure:
"""Open a ``.gle`` file (or GLE source text) as a gleplot :class:`Figure`.
Convenience wrapper around
:func:`gleplot.parser.recognizer.parse_gle_figure` that returns just the
reconstructed figure (discarding recovery warnings). Use
``parse_gle_figure`` directly when you need the warnings list.
Parameters
----------
path : str or pathlib.Path
Path to a ``.gle`` file, or raw GLE source text.
base_dir : str or pathlib.Path, optional
Directory for resolving relative ``data`` references when ``path`` is
raw source text.
Returns
-------
Figure
"""
from .parser.recognizer import parse_gle_figure
return parse_gle_figure(path, base_dir=base_dir).figure
[docs]
def gca():
"""Get current axes."""
if _current_figure is None:
figure()
return _current_figure.gca()
[docs]
def gcf():
"""Get current figure."""
if _current_figure is None:
figure()
return _current_figure
[docs]
def plot(*args, **kwargs):
"""Plot on current axes."""
return gca().plot(*args, **kwargs)
[docs]
def scatter(*args, **kwargs):
"""Scatter on current axes."""
return gca().scatter(*args, **kwargs)
[docs]
def bar(*args, **kwargs):
"""Bar chart on current axes."""
return gca().bar(*args, **kwargs)
[docs]
def fill_between(*args, **kwargs):
"""Fill between on current axes."""
return gca().fill_between(*args, **kwargs)
[docs]
def errorbar(*args, **kwargs):
"""Error bar plot on current axes."""
return gca().errorbar(*args, **kwargs)
[docs]
def text(*args, **kwargs):
"""Add text annotation on current axes."""
return gca().text(*args, **kwargs)
def axvline(*args, **kwargs):
"""Vertical reference line on current axes."""
return gca().axvline(*args, **kwargs)
def axhline(*args, **kwargs):
"""Horizontal reference line on current axes."""
return gca().axhline(*args, **kwargs)
def axvspan(*args, **kwargs):
"""Shaded vertical band on current axes."""
return gca().axvspan(*args, **kwargs)
def axhspan(*args, **kwargs):
"""Shaded horizontal band on current axes."""
return gca().axhspan(*args, **kwargs)
[docs]
def imshow(*args, **kwargs):
"""Display gridded data as a heatmap on current axes."""
return gca().imshow(*args, **kwargs)
[docs]
def contour(*args, **kwargs):
"""Draw contour lines on current axes."""
return gca().contour(*args, **kwargs)
[docs]
def tripcolor(*args, **kwargs):
"""Scattered-data heatmap on current axes."""
return gca().tripcolor(*args, **kwargs)
[docs]
def tricontour(*args, **kwargs):
"""Scattered-data contour lines on current axes."""
return gca().tricontour(*args, **kwargs)
[docs]
def colorbar(*args, **kwargs):
"""Attach a colorbar to the current figure's heatmap axes."""
return gcf().colorbar(*args, **kwargs)
[docs]
def subplots(
nrows: int = 1,
ncols: int = 1,
figsize=None,
dpi=100,
style=None,
graph=None,
marker=None,
sharex: bool = False,
sharey: bool = False,
data_prefix=None,
height_ratios=None,
width_ratios=None,
):
"""
Create a figure and a set of subplots.
Convenience function matching ``matplotlib.pyplot.subplots()``.
Parameters
----------
nrows : int, optional
Number of rows of subplots. Default: 1
ncols : int, optional
Number of columns of subplots. Default: 1
figsize : tuple, optional
Figure size (width, height) in inches. If None, auto-scales
based on grid size (6 inches per column, 4 inches per row).
dpi : int, optional
Dots per inch. Default: 100
style : GLEStyleConfig, optional
Style configuration.
graph : GLEGraphConfig, optional
Graph configuration.
marker : GLEMarkerConfig, optional
Marker configuration.
sharex : bool, optional
If True, all subplots share the same x-axis. Only the bottom row
will show x-axis labels and ticks. Default: False
sharey : bool, optional
If True, all subplots share the same y-axis. Only the leftmost column
will show y-axis labels and ticks. Default: False
data_prefix : str, optional
Custom prefix for data file names (e.g., 'test9' creates 'test9_0.dat', 'test9_1.dat').
If None, uses global counter with ``data_`` prefix. Used verbatim, so
it must be usable as a GLE data filename: whitespace, control
characters and any of ``! " + / \\`` raise ``ValueError``.
height_ratios : sequence of float, optional
Relative height of each of the ``nrows`` subplot rows, matplotlib-
``gridspec`` style (e.g. ``[3, 3, 3, 1, 4]`` for 5 rows whose 4th is
thin). Must have length ``nrows`` if given. ``None`` (default) keeps
every row the same height -- the historical behaviour, byte-
identical output. See :class:`gleplot.figure.Figure` for full
semantics (validated against the actual row count at GLE-generation
time).
width_ratios : sequence of float, optional
Relative width of each of the ``ncols`` subplot columns. Same
semantics as ``height_ratios``, for columns; must have length
``ncols`` if given.
Returns
-------
fig : Figure
The figure object.
axes : Axes or list of Axes
A single Axes if nrows*ncols == 1, otherwise a list of Axes
arranged in row-major order.
Examples
--------
Single plot:
>>> fig, ax = glp.subplots()
>>> ax.plot(x, y)
2x2 grid:
>>> fig, axes = glp.subplots(2, 2, figsize=(12, 10))
>>> axes[0].plot(x, y1) # top-left
>>> axes[1].scatter(x, y2) # top-right
>>> axes[2].bar(x, y3) # bottom-left
>>> axes[3].plot(x, y4) # bottom-right
Shared x-axis (stacked plots):
>>> fig, axes = glp.subplots(3, 1, sharex=True, figsize=(8, 12))
>>> # Only bottom subplot shows x-axis label and ticks
Stacked panels with a short separator row (unequal row heights):
>>> fig, axes = glp.subplots(3, 1, sharex=True, figsize=(3.4, 4),
... height_ratios=[3, 3, 1])
>>> # axes[2] gets 1/7 of the plotting height, axes[0]/axes[1] get 3/7 each
"""
global _current_figure
if figsize is None:
figsize = (max(6, 6 * ncols), max(4, 4 * nrows))
fig = Figure(
figsize=figsize,
dpi=dpi,
style=style,
graph=graph,
marker=marker,
sharex=sharex,
sharey=sharey,
data_prefix=data_prefix,
height_ratios=height_ratios,
width_ratios=width_ratios,
)
_current_figure = fig
axes_list = []
for idx in range(1, nrows * ncols + 1):
ax = fig.add_subplot(nrows, ncols, idx)
axes_list.append(ax)
if len(axes_list) == 1:
return fig, axes_list[0]
return fig, axes_list
[docs]
def xlabel(label: str):
"""Set x label on current axes."""
return gca().set_xlabel(label)
[docs]
def ylabel(label: str):
"""Set y label on current axes."""
return gca().set_ylabel(label)
[docs]
def title(label: str):
"""Set title on current axes."""
return gca().set_title(label)
[docs]
def legend(**kwargs):
"""Add legend to current axes."""
return gca().legend(**kwargs)
[docs]
def savefig(filepath: str, **kwargs):
"""Save current figure."""
return gcf().savefig(filepath, **kwargs)
[docs]
def show():
"""Show current figure (placeholder)."""
print(f"Figure saved to {gcf().figsize}")
[docs]
def view(dpi=None, format="png"):
"""Display current figure inline (in Jupyter notebooks).
Parameters
----------
dpi : int, optional
Resolution in dots per inch. If None, uses figure's dpi setting.
format : {'png', 'pdf'}, optional
Output format. Default is 'png' for inline display.
Returns
-------
Path or None
Path to the generated file, or None when displayed inline in Jupyter.
Examples
--------
>>> import gleplot as glp
>>> fig = glp.figure()
>>> ax = fig.add_subplot(111)
>>> ax.plot([1, 2, 3], [1, 4, 9])
>>> glp.view() # Display in notebook
"""
return gcf().view(dpi=dpi, format=format)
[docs]
def close(fig=None):
"""Close figure."""
global _current_figure
if fig is None:
if _current_figure:
_current_figure.close()
_current_figure = None
else:
fig.close()
__all__ = [
"Figure",
"Axes",
# Light validation of a GLE tick-label number format string ("fix 1",
# "sci 2 10", ...), for callers building one interactively.
"validate_tick_format",
"BrokenAxes",
"figure",
"gca",
"gcf",
"plot",
"scatter",
"bar",
"fill_between",
"errorbar",
"text",
"axvline",
"axhline",
"axvspan",
"axhspan",
"imshow",
"contour",
"tripcolor",
"tricontour",
"colorbar",
"subplots",
"xlabel",
"ylabel",
"title",
"legend",
"savefig",
"view",
"show",
"close",
"rgb_to_gle",
"get_color_palette",
"get_gle_marker",
"mathtext_to_gle",
"GLECompiler",
"GLEStyleConfig",
"GLEGraphConfig",
"GLEMarkerConfig",
"GlobalConfig",
"open_gle",
"DataSource",
"InlineData",
"ColumnRef",
"GridRef",
"DataProvider",
"TableData",
"DictDataProvider",
"DanglingSourceRef",
"DanglingSourceWarning",
]