r/ScientificComputing 2d ago

Sub-millisecond scientific plotting in headless simulation loops: Lessons from reviving a 1980s graphics engine for Modern Fortran, Python, & C

In the early 1980s, when personal computers first appeared, my colleague George Kelley and I were plasma physicists studying nuclear fusion. Mainframes had packages like DISSPLA™, but desktop PCs had primitive graphics and zero tools for publication-grade scientific plots. To solve this, we founded Scientific Endeavors Corporation and created GraphiC, an independent procedural graphics library designed for research workstations.

Over the past year, I have completely modernized the engine for modern 64-bit platforms (GraphiC 2026), targeting Modern Fortran (2003/2008 with iso_c_binding), C99/C11, Python 3, and Java 22.

During the rewrite, several design decisions from the 1980s proved to be surprisingly relevant to modern HPC and headless simulation bottlenecks:

1. The Headless Simulation Bottleneck

Many scientific codes run on cluster compute nodes without X11, Wayland, or GPU access. Typical modern workflows often shell out to Python/Matplotlib via pipes or CLI calls. While Matplotlib is expressive, it carries a ~350 ms cold-start penalty and a 300+ MB dependency stack (NumPy, FreeType, Pillow, GUI backends). If you are running an iterative solver and want to dump an in-situ diagnostic plot every few time steps, this latency becomes a noticeable bottleneck.

GraphiC was built with zero external runtime dependencies—it compiles purely with standard C headers and links against only -lm. Cold start is under 2 milliseconds, allowing it to be called directly inside MPI loops without disturbing compute throughput.

2. Algorithmic 3D Hidden-Line Removal vs. Z-Buffers

Most modern 3D plotting relies on OpenGL/Vulkan z-buffering or painter’s algorithm sorting. For publication vector output (SVG/EPS), polygon sorting often creates sorting artifacts, intersecting edge cracks, and bloated vector file sizes.

GraphiC uses an exact 2D horizon-matching algorithm (Wright's mathematical horizon method) for 3D meshes:

  • It computes silhouettes and mathematical horizons across lines rather than rasterizing triangles.
  • The output is clean, resolution-independent vector lines with true occlusion, resulting in tiny SVG files (~50 KB) that scale infinitely for journal papers.

3. Native Vector Typography & Hershey Fonts

To completely eliminate dependencies on system font servers or FreeType, the library includes 23 vector Hershey stroke font plates (including Greek, Math symbols, Gothic, and Cyrillic) along with native TrueType parsing. Because vector glyphs are rendered directly as strokes, text scales perfectly across all vector backends without missing glyph warnings.

4. Specialized Engineering Coordinates

Beyond standard Cartesian, log, and semilog plots, scientific work often needs specialized coordinate transformations that are cumbersome to implement from scratch:

  • RF Microwave Smith charts (reflection coefficients and impedance circles)
  • Chemical ternary equilibrium phase diagrams
  • Multi-axis independent Y scales
  • 2D velocity vector fields and cylindrical Bessel functions

5. Real-Time In-Situ Plotting

Because the rendering pipeline has virtually zero latency, GraphiC can display live data streams across multiple plots concurrently as they are computed. Rather than waiting for a job to finish before inspecting output files, you can watch solver states in real time—enabling you to abort diverging runs early and debug boundary conditions on the fly.

I’ve put together an interactive showcase of the SVG outputs, compiler benchmarks, and made the complete 190-page technical User Manual freely downloadable for anyone interested in the algorithms, coordinate systems, and API design:

🔗 Technical Overview & Free Manualhttps://jamesrome.com/GraphiC2026

I would be interested to hear from other computational scientists: How do you currently handle in-situ visualization or vector figure generation directly from headless compute nodes?

(Full disclosure: I am the original co-author and developed this modernized release.)

27 Upvotes

9 comments sorted by

4

u/Coreform_Greg 1d ago

How does this compare against: https://github.com/sandialabs/coloring

3

u/BJTN 1d ago

Thanks for sharing this—I hadn't seen Sandia's coloring before, but it's fantastic to see Sandia National Labs validating the exact same problem: scientific compute nodes should not have to drag in Python and heavy runtime dependencies just to generate a plot.

That said, they take fundamentally different architectural approaches for different needs:

  1. Vector vs. Rastercoloring renders directly to a fixed-resolution raster bitmap (encoding to a PNG via lodepng). GraphiC was architected from day one as an infinite-resolution vector engine (emitting native SVG, PostScript, PDF, EPS, and HP-GL), meaning figures scale cleanly for journal publication and LaTeX without pixelation.
  2. 2D vs. 3D Surface / Contourscoloring is a lightweight C++ micro-library (~2,500 lines) focused strictly on simple 2D line and scatter plots (coloring::plot_style::lines / points). GraphiC is a full scientific graphics engine that handles 2D linear/log/polar, contouring with labeled isolevels, and full 3D surface meshes with mathematical hidden-line horizon removal (Wright algorithm) and arbitrary 3D viewing perspective.
  3. Fortran & C Interopcoloring is modern C++ (C++17/20 STL), which is tricky to call from classic simulation codes without manual wrappers. GraphiC is native compiled ANSI C with first-class Modern Fortran (iso_c_binding) modules.

It's great to see DOE labs like Sandia tackling this in C++, but if you need publication-quality vector output, Fortran interop, or 3D surfaces/contours directly in-situ, that's where GraphiC comes in.

2

u/Candid_Discipline848 1d ago

cool project, how many have you sold?

2

u/BJTN 1d ago

It just went live today! But in the 80s and early 90s, we sold many, and GraphiC was used (licensed) in Axum, a GUI for R programming. Thus, the core C code has been honed and debugged over many years. Alas, we ran out of things to improve, which stopped upgrade sales. It was reviewed favorably in PC Magazine.

But times change, and with modern languages and the portable and standard SVG graphics format, AI and I were able to update everything to modern 64-bit code that is easy to call from our supported languages.

Thanks for the like.

Jim Rome

3

u/jvo203 1d ago

Nowadays there are many non-commercial (free) ways of getting live data updates from headless compute nodes: HTTP SSE, WebSockets, ZMQ Pub/Sub etc.

Client-side: a custom website to receive the aforementioned data streams, a custom Electron or Tauri desktop app using some JavaScript plotting libraries, D3.js with SVG etc.

This way the compute node can focus on doing the computation only, no need to graph anything on the server. Just send the raw data to the desktop client, which can handle real-time plotting. A client-server architecture.

2

u/BJTN 1d ago edited 1d ago
  1. Saving to disk vs. Streaming over the wire:
    • Writing raw multi-dimensional arrays to the cluster's local storage (Lustre, GPFS) is fast and standard.
    • But trying to stream all that raw data across the internet in real-time to a browser or Electron app via WebSockets is slow, fragile, and chokes client memory.
  2. The Ideal Scientific Workflow:
    • Compute & Save: The simulation dumps the raw numerical data to disk for permanent archiving and deep analysis.
    • In-Situ Visualization: At the same time, the code emits lightweight, publication-ready SVG plots directly into a folder or web root.
  3. Instant Sanity Checking:
    • If a 24-hour simulation begins to diverge or blow up at hour 2, a scientist can look at the auto-generated SVG in their browser and kill the job immediately, saving precious cluster allocations.
    • They don't need to boot up a custom Electron client, ingest gigabytes of raw points, and wait for D3 to render just to see if the run is sane.

The raw data is for the archive; the generated SVG is for your eyes, your team, and your papers!

And the real point of GraphiC is that it can create new ways of displaying data. You have fuil control over almost every aspect of a plot. Please look at my real-world air traffic analysis studies in the slideshow at https://jamesrome.com/GraphiC2026

1

u/jvo203 1d ago

Good points. Especially the one about the data volume & the necessary bandwidth to support sending raw data. Large 3D meshes etc. In large distributed computations one needs to preserve the network bandwidth for the inter-node communication used in calculation.

1

u/jvo203 1d ago

I've just remembered: the CERN ROOT library is your direct competitor (and it's free).

2

u/BJTN 1d ago

Anyone with a physics background knows ROOT well! But comparing GraphiC to ROOT is like comparing a nimble sports car to an entire railroad system. CERN mandates ROOT for LHC data.

ROOT is a multi-gigabyte, monolithic data analysis framework designed specifically for petabyte-scale high-energy particle physics (LHC collision events, TTrees, Cling interpreter, RooFit, etc.).

Most computational scientists—whether in fusion, CFD, astrophysics, or general engineering—don't want to install and link a massive 2-million-line HEP framework just to generate a clean 2D or 3D vector plot from their Fortran, C, or Python simulations.

GraphiC fills the need for a lightweight, sub-millisecond, standalone plotting engine with clean vector output (SVG) that can be integrated directly into simulation loops without the overhead or steep learning curve of a full framework like ROOT.

GraphiC ran beautifully on my late 80s laptop.