A Python library that provides a matplotlib-compatible API for creating scientific plots that directly generate GLE (Graphics Layout Engine) scripts for publication-quality vector graphics.
import numpy as np
import gleplot as glp
# Create data
x = np.linspace(0, 2*np.pi, 100)
# Create figure and plot
fig = glp.figure(figsize=(8, 6))
ax = fig.add_subplot(111)
ax.plot(x, np.sin(x), color='blue', label='sin(x)')
ax.plot(x, np.cos(x), color='red', linestyle='--', label='cos(x)')
# Configure plot
ax.set_xlabel('x (radians)')
ax.set_ylabel('y')
ax.set_title('Trigonometric Functions')
ax.legend()
# Save as PDF (auto-compiles via GLE)
fig.savefig('trig.pdf')
# Or save as GLE script for manual editing
fig.savefig('trig.gle')
# Keep the script, compiled output, and data sidecars together
fig.savefig('trig.pdf', folder=True)✨ Matplotlib-Compatible API - All familiar functions work identically
✨ Direct GLE Generation - Optimized script output (1-2 KB)
✨ Vector Graphics - PDF, PNG, EPS export with publication quality
✨ Full Plotting Support - Lines, scatter, bars, fill_between, errorbar
✨ Error Bars - Symmetric, asymmetric, vertical and horizontal
✨ File-Based Series - Plot directly from existing data columns (no extra sidecar files)
✨ Subplots - Multi-panel figures with flexible grid layouts
✨ Subplot Layout Control - Fine-tune margins and inter-panel spacing with subplots_adjust
✨ Publication Ready - Suitable for all major academic journals
✨ Lightweight - Pure Python, minimal dependencies
gleplot also ships a desktop editor (PySide6) for building figures without writing code: load data, pick columns, style series, arrange subplots, annotate, and export -- all with a live preview.
pip install "gleplot[gui]"gleplot-gui✨ Live Preview - Debounced, async GLE compile as you edit, as a vector SVG by default (with an automatic, sticky PNG fallback if SVG isn't usable)
✨ On-Canvas Annotations - Add, drag, double-click-edit, and delete free-form text labels directly on the preview, kept in sync with a dedicated Texts tab
✨ Data Manager - Load CSV/.dat files, pick columns, import data or reference the file in place
✨ Named Data Columns - Generated .dat sidecars carry real column names (from your series labels) instead of anonymous placeholders
✨ Property Panels - Layout, Figure, Axes, Series, and Texts tabs for point-and-click styling
✨ Native .gle Files - Save and open your work directly as .gle (the same format GLE renders) via File ▸ Save / Open -- unrecognized content is preserved as raw GLE
✨ Export Dialog - PDF, PNG, EPS, SVG, JPG, or raw GLE script, with an optional folder bundle
✨ Undo/Redo - Full editing history
✨ Programmatic-.gle Preview - Files using GLE programming constructs open as a read-only render + export
The editor needs GLE 4.3+ installed and discoverable (via GLE_PATH or PATH) to render the live preview and export non-.gle formats -- see Installation above. The status bar shows the detected GLE path (or "not found").
Prebuilt Windows and macOS builds are attached to each GitHub Release.
See the GUI Editor Guide for a full walkthrough, and examples/gui/ for a ready-to-open sample project.
📚 Live Sphinx Documentation - Complete API reference and guides
Key Documentation Resources:
- GUI Editor Guide - Desktop editor walkthrough, project files, troubleshooting
- Configuration System - Customize gleplot appearance and behavior
- Configuration API - Complete configuration reference
- Semantic Versioning - Automatic version management
- Versioning Quick Reference - Common version bump patterns
- Testing Quick Reference - Fast commands and examples
- Test Structure - Test organization and architecture
- Graphics Testing - Complete graphics testing documentation
- Python 3.7+
- numpy
-
GLE 4.3+ (for PDF/PNG/EPS compilation)
# Verify installation gle -infoInstall GLE from the official upstream sources:
- Preferred (all platforms): Download prebuilt releases from https://github.com/vlabella/GLE/releases/latest
- Windows:
.exeinstaller - macOS:
.dmg - Linux:
.zip
- Windows:
- Alternative: Download from the official GLE site: https://glx.sourceforge.io/download/
- Build from source: Follow the platform-specific build instructions in the upstream README: https://github.com/vlabella/GLE/blob/main/README.md
GLE upstream also recommends installing runtime dependencies:
- Ghostscript
- LaTeX distribution (e.g., TeX Live or MiKTeX)
Quick first-time verification:
# Locate Ghostscript/LaTeX and other runtime dependencies gle -finddeps # Confirm GLE is installed and discover paths gle -info
- Preferred (all platforms): Download prebuilt releases from https://github.com/vlabella/GLE/releases/latest
pip install -e .Or in development mode:
pip install -e ".[dev]"gleplot/
├── src/gleplot/ # Source code
│ ├── __init__.py # Main API
│ ├── figure.py # Figure class
│ ├── axes.py # Axes class
│ ├── colors.py # Color utilities
│ ├── markers.py # Marker definitions
│ ├── dataio.py # Delimited data-file loading
│ ├── writer.py # GLE script writer
│ ├── compiler.py # GLE compiler wrapper
│ ├── config.py # Configuration system
│ ├── parser/ # Parse existing .gle back into the object model
│ └── gui/ # PySide6 desktop editor
│
├── tests/ # Test suite
│ ├── unit/ # Unit tests
│ ├── integration/ # Integration tests
│ ├── parser/ # GLE parser tests
│ ├── gui/ # GUI editor tests
│ ├── agent/ # Agent tests
│ ├── test_gleplot.py # Core test suite
│ └── generate_test_graphics.py # Graphics generation tests
│
├── examples/ # Example scripts
│ ├── basic/ # Basic plotting examples
│ │ ├── line_plots.py
│ │ ├── scatter_plots.py
│ │ ├── bar_charts.py
│ │ └── error_bars.py
│ ├── advanced/ # Advanced examples
│ │ ├── subplots.py
│ │ ├── shared_axes.py
│ │ ├── fill_between.py
│ │ ├── log_scale.py
│ │ └── combined_plots.py
│ └── gleplot_examples.py # Main examples runner
│
├── docs/ # Documentation
│ ├── guides/ # User guides
│ ├── agent/ # Development notes
│ └── source/ # Sphinx source files
│
├── pyproject.toml # Package configuration
├── README.md # This file
└── LICENSE # GPL-2.0+
ax.plot(x, y, color='blue', linestyle='--', label='data')ax.scatter(x, y, color='red', marker='o', s=50, label='points')ax.bar([1, 2, 3], [10, 20, 30], color=['red', 'green', 'blue'])ax.fill_between(x, y1, y2, color='lightblue', alpha=0.3)# Symmetric vertical error bars
ax.errorbar(x, y, yerr=0.5, marker='o', color='blue', label='Data')
# Asymmetric vertical error bars
ax.errorbar(x, y, yerr=([lower_arr], [upper_arr]), marker='s', fmt='none')
# Both vertical and horizontal error bars
ax.errorbar(x, y, yerr=yerr, xerr=xerr, marker='o', capsize=3)# Error bars from existing file columns (1-based column indices)
ax.errorbar_from_file(
'experiment.dat',
x_col=1,
y_col=2,
yerr_col=3,
marker='o',
color='blue',
label='Measurement'
)
# Overlay fit/model line from the same file without creating data_*.dat
ax.line_from_file(
'experiment.dat',
x_col=1,
y_col=4,
color='red',
linestyle='--',
linewidth=2,
label='Model fit'
)# Creates trig.gleplot/trig.pdf, trig.gleplot/trig.gle, and data files
fig.savefig('trig.pdf', folder=True)# Plot data with different scales on same graph
fig = glp.figure()
ax = fig.add_subplot(111)
# Plot on left y-axis (default)
ax.plot(days, temperature, color='red', label='Temperature', yaxis='y')
ax.set_ylabel('Temperature (°C)', axis='y')
ax.set_ylim(10, 30, axis='y')
# Plot on right y-axis
ax.plot(days, humidity, color='blue', label='Humidity', yaxis='y2')
ax.set_ylabel('Humidity (%)', axis='y2')
ax.set_ylim(30, 90, axis='y2')
# Log scale on secondary axis
ax.set_yscale('log', axis='y2')
ax.legend()
fig.savefig('dual_axis.pdf')# Using subplots() convenience function
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].errorbar(x, y4, yerr=err) # bottom-right
fig.savefig('grid.pdf')
# Using add_subplot() method
fig = glp.figure(figsize=(14, 6))
ax1 = fig.add_subplot(1, 2, 1) # left panel
ax2 = fig.add_subplot(1, 2, 2) # right panel
# Shared axes for tighter layouts (stacked plots)
fig, axes = glp.subplots(3, 1, sharex=True, figsize=(8, 10))
# Only bottom subplot shows x-axis label and ticks
axes[0].plot(x, signal)
axes[1].plot(x, noise)
axes[2].plot(x, combined)
axes[2].set_xlabel('Time') # Only need to label bottom
# Shared axes for side-by-side comparisons
fig, axes = glp.subplots(1, 3, sharey=True, figsize=(18, 5))
# Only leftmost subplot shows y-axis label and ticks
axes[0].scatter(x1, y1)
axes[0].set_ylabel('Response') # Only need to label left
axes[1].scatter(x2, y2)
axes[2].scatter(x3, y3)
# Fine-tune multi-panel layout (matplotlib-compatible)
fig.subplots_adjust(
left=0.12,
right=0.98,
bottom=0.1,
top=0.92,
wspace=0.35,
hspace=0.4,
)ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_title('My Plot')
ax.set_xlim(0, 10)
ax.set_ylim(0, 100)
ax.set_xscale('log')
ax.set_yscale('log')
ax.legend(loc='upper left')Run the comprehensive test suite:
cd tests
python -m pytest test_gleplot.py -vOr run directly:
python test_gleplot.pyExpected output: a comprehensive test suite (unit, integration, parser, and GUI tests), all passing
Run the example scripts:
cd examples
python gleplot_examples.pyOr run specific example categories:
# Basic examples
python basic/line_plots.py
python basic/scatter_plots.py
python basic/bar_charts.py
python basic/error_bars.py
# Advanced examples
python advanced/subplots.py
python advanced/shared_axes.py
python advanced/secondary_yaxis.py
python advanced/fill_between.py
python advanced/log_scale.py
python advanced/combined_plots.py
python advanced/multiple_styles.pyEach example generates GLE script files and optionally compiles them to PDFs.
fig = glp.figure(figsize=(8, 6), dpi=100)ax = fig.add_subplot(111)
ax.plot(...)
ax.scatter(...)
ax.bar(...)
ax.fill_between(...)glp.figure()
glp.plot(x, y)
glp.scatter(x, y)
glp.xlabel('X')
glp.savefig('plot.pdf')| Feature | gleplot | matplotlib |
|---|---|---|
| API | 100% compatible | Reference implementation |
| Output | GLE vector graphics | PNG/PDF raster + vector |
| File size | 1-2 KB script | 50-100 KB PNG |
| Compilation | GLE → PDF/PNG | Built-in |
| Learning curve | None (familiar API) | Moderate |
| Use case | Publication graphics | General-purpose plotting |
If compilation fails, ensure GLE is installed and in PATH:
which gle
gle -infoMake sure gleplot is properly installed:
pip install -e .Run tests with verbose output:
python -m pytest tests/ -vvContributions welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new features
- Run:
python -m pytest tests/ - Submit pull request
gleplot is licensed under GPL-2.0+ (compatible with GLE license).
- GLE Documentation: https://glx.sourceforge.io/
- GLE GitHub: https://github.com/vlabella/GLE
- Matplotlib Documentation: https://matplotlib.org/
- NumPy Documentation: https://numpy.org/
✅ Production Ready
✅ All Tests Passing
✅ Multiple Example Categories
✅ Full Documentation
✅ Automatic Semantic Versioning
- GitHub: https://github.com/benhuddart/gleplot
- Issues: https://github.com/benhuddart/gleplot/issues
- Documentation: https://benhuddart.github.io/gleplot/
For questions, issues, or feature requests, please open an issue on GitHub.
Happy plotting! 📊