GraphiC.jl: Zero-latency vector scientific plotting engine (pure SVG output)

Sorry about the formatting of my original post—I used an AI assistant to help draft it, and I realize now that the bullet points and style made it look like automated spam!

I am a retired plasma physicist (MIT Sc.D. 1970, worked at a national laboratory for many years). Back in the 1980s, I wrote a scientific graphics library in C called GraphiC. Over the past couple of months, I modernized the C99 core and added a native vector SVG driver with zero external dependencies (just standard libc and libm).

I have been learning Julia, so I put together a direct Julia module that interfaces with the C library via ccall to emit pure vector SVG plots with sub-millisecond execution.

Here is a simple example:

julia

using GraphiC
x = range(0, 10, length=200)
y = sin.(x) .* exp.(-0.2 .* x)
GraphiC.plot(x, y;
title=“Damped Harmonic Motion”,
xlabel=“Time (s)”,
ylabel=“Amplitude”,
color=GraphiC.BLUE,
thick=1.5,
grid=true,
filename=“damped_sine.svg”)

The 2D C engine and modern user manual are available on my personal website at jamesrome dot com (the Julia wrapper is not yet an official registered package).

As someone new to Julia, I would really appreciate feedback from experienced Julia programmers on whether wrapping a lightweight C vector engine like this is useful to the community, and how I can structure the wrapper to be more idiomatic.

Welcome to Discourse @jamesrome. Please do not use AI to create your posts here — we’re humans here to talk with other humans.

Tell us about the project yourself, please!

You should be able to edit your post above, and links to GitHub should be allowed even for first-time posters. It seems, though, that your GitHub account is non-existent.

I did a search for this and found the website. There is a free community edition of the software and a commercial edition for $295. There is also a manual, worth browsing if you are considering this.

Thanks for the warm welcome, Matt, and my apologies!

I’m an 83-year-old retired plasma physicist, and I made the mistake of letting an AI assistant draft that initial post for me. I realize now how canned and robotic it sounded—definitely a lesson learned.

My actual GitHub account is jimrome (not jamesarome—another AI mix-up). I haven’t pushed the GraphiC.jl repo to GitHub yet because, as a newcomer to Julia, I wanted to get a feel from the community first on whether a direct C wrapper like this is even of interest or how best to structure it.

I will edit the main post now to describe the project directly in my own words. Thanks for the guidance and for keeping the community human!

I have created the repositories on GitHub under my real username (jimrome):

Let me explain why I created GraphiC so many years ago, and why I think it is still relevant. If you have the usual sort of data, you can plot it using Excel. or its ilk. But real scientific insight is obtained by plotting data in new ways, which is why you need a library and not a program with many plot types. The full version of GraphiC can create quite amazing plots. I hope you watch the slideshow on my site to see some of the ways I analyzed air traffic. I wrote the seminal paper on “ripple delay,” which is caused by crews not staying together thus delaying multiple flights; one delay early in the day can create exponential delays later on.
I also found that zooming vector plots allowed me to see the overall picture while allowing zooming to see individual details. Most of the images in the gallery can be zoomed—try it.
The other feature is that GraphiC plots require no external libraries, are very fast, create small code, and can display data as they are generated (instead of after the fact). Try it and see for yourself.

I went through the example plots on the website, and they look great.
Julia has a Plots.jl library which is a frontend/interface to several backend plotting libraries. If you are so inclined, it would be great to have your package interface with Plots.jl. The interface may not be sufficient to capture all the features of your library, but at least it will get folks using it if they prefer.

I personally use gnuplot and the Julia interface Gnuplot.jl which doesn’t produce “pretty” plots, but I am very used to it. Nonetheless, I am also thinking myself of switching to Plots.jl to get access to several backends.

Thanks for the suggestion, Affan.

You talked me into it—I just implemented a Plots.jl backend for GraphiC via a Julia package extension.

If you have Plots loaded, you can now activate the engine with:

julia

using Plots

import GraphiC: graphic

graphic()

p = plot(1:10, sin, label=“sin”, color=:blue, lw=2)

plot!(p, 1:10, cos, label=“cos”, color=:red, linestyle=:dash)

savefig(p, “output.svg”)

It routes directly to libgraphic under the hood, producing crisp vector SVG with zero external dependencies and essentially no latency.

As you suspected, Plots.jl’s standard abstractions don’t cover all of GraphiC’s specialized features (such as RF Smith charts, polar contours, or 3D perspective with automated hidden-line suppression), but those remain available through the native API. I also added plot!, scatter!, and automatic legends to standalone GraphiC.jl for users who prefer to skip the Plots.jl overhead altogether.

Once GraphiC is registered in the General Registry, I’ll submit a PR upstream to Plots.jl so graphic() works right out of the box with just using Plots.

Give it a spin if you get a chance—I’d be interested to hear how it works for your workflow. It is on the GraphiC Web page link.

What about Makie.jl? Can this project improve the user experience of Makie.jl?

Agree, they look great. Reminds more of some the fanciest TikZ drawings I have seen. Impressive!

Just as CairoMakie is a backend for Makie, we will create a package extension or backend that implements Makie’s backend display hooks:

julia

using Makie, GraphiC
# Activate GraphiC as the vector backend
graphic_backend()
# Users write standard Makie code:
fig = Figure()
ax = Axis3(fig[1, 1], title=“Bessel 3D”)
surface!(ax, x, y, z)
# GraphiC renders the true hidden-line vector SVG!
save(“publication_figure.svg”, fig)

Thus, GraphiC solves Makie’s biggest vector limitations by providing analytic 3D hidden-line removal, zero dependencies, and lightweight, clean SVG output. But 3D support is in the paid version.

The Makie support is now up on my Web site

When George Kelley and I started writing GraphiC in the 1980s to plot our fusion equilibria, we had one ironclad rule: vector graphics only. We insisted that every curve, axis, and 3D surface had to be mathematically defined so you could zoom in all the way to inspect the physics without seeing jagged raster pixels. And when you put a 3D surface on paper, it had to have true, clean hidden-line removal—not fuzzy shading that hides the details.

Fast forward 40 years to Julia and Makie.jl. Makie is a very impressive modern plotting system with a clean syntax, but it suffers from a dilemma that every physicist and engineer will recognize immediately when trying to plot in 3D:

  1. GLMakie is raster-only. If you want interactive 3D, you use OpenGL. It looks nice on your screen, but the moment you save a figure for a journal article or a talk, you get a bitmap PNG. You can’t zoom in, and you can’t scale it cleanly. Worse, if you try to run it on a headless Linux cluster or over SSH without an X-server, it refuses to run because there is no GPU or display.
  2. CairoMakie chokes on 3D. Cairo is great for 2D vector plots, but for 3D surfaces it tries to simulate 3D by chopping your mesh into thousands of tiny painter’s-algorithm polygons. You end up with a monstrous 25 MB SVG file filled with seams, z-fighting glitches, and slow rendering that brings web browsers to their knees.

How GraphiC fixes this for Makie

By plugging GraphiC into Makie as a dedicated vector screen (graphic_makie()), Makie users get something they simply haven’t had before:

  • True Analytical Hidden-Line Removal: Instead of dumping thousands of polygon triangles, GraphiC uses Margaret Wright’s horizon algorithm to calculate mathematically exact line-segment visibility. You get a razor-sharp, publication-quality 3D vector SVG that is 40 KB instead of 25 MB. You can zoom in indefinitely, and it renders instantly.
  • Runs Anywhere (Headless HPC & CI/CD): GraphiC is pure, self-contained C. It has no dependencies on OpenGL, GLFW, X11, or Mesa. You can drop it into a batch simulation on a headless supercomputer or a Docker container, and it just emits clean SVGs without complaint.
  • Zero Overhead: Because we hooked it up as a Julia package extension, Makie is only loaded if you actually use it. If you don’t use Makie, GraphiC stays lean, fast, and 100% C-pure.

You write standard Makie code, but you get GraphiC’s mathematical rendering engine under the hood:

julia

using Makie

import GraphiC: graphic_makie
# Tell Makie to use GraphiC for vector output
graphic_makie()
# Standard Makie 3D surface
x = range(-3.0, 3.0, length=30)
y = range(-3.0, 3.0, length=30)
z = [sin(sqrt(xi^2 + yi^2)) for xi in x, yi in y]
fig = Figure()
ax = Axis3(fig[1, 1], title=“3D Bessel Surface”)
surface!(ax, x, y, z; colormap=:viridis)
# Emits a compact, crisp vector SVG with true hidden-line removal:
save(“bessel_surface.svg”, fig)

In short: Makie gives you the modern Julia interface, and GraphiC provides the rock-solid, 40-year-tested analytical vector engine that modern graphics libraries left behind.

By that time, two Geophysicist started to write GMT that was mainly vector graphics too (in PostScript) plus raster, because grids are discrete by nature.

It still lives today (in Julia it’s GMT.jl)

GraphiC is not registered? Where do I find the Makie extension?
Could you possibly drop the links here? Thanks.

Could you possibly drop the links here? Thanks.

]
add https://github.com/jimrome/GraphiC.jl

but now I am running into trouble that I would like help with.

julia> import GraphiC: graphic_makie
WARNING: Imported binding GraphiC.graphic_makie was undeclared at import time during import to Main.

julia> graphic_makie()
ERROR: UndefVarError: `graphic_makie` not defined in `Main`
Suggestion: this global was defined as `GraphiC.graphic_makie` but not assigned a value.
Stacktrace:
 [1] top-level scope
   @ REPL[9]:1

Yes, found that before, but thanks. Alas, it does not work (Makie backend…).

Hi Jake,

Thanks for testing it out! You caught me mid-update—I had tested the new Makie extension locally on my Mac, but hadn’t pushed the commit containing GraphiCMakieExt.jl and graphic_makie to GitHub yet. You pulled the previous commit which didn’t know about Makie yet.

I’ve just bumped the repo to v7.4.1 and pushed the update live to GitHub: GitHub - jimrome/GraphiC.jl: Scientific vector plotting engine for Julia with zero dependencies and native SVG output · GitHub.

One important thing to note: the public GitHub repo includes the free 2D Community Edition library. The 3D surface meshes with Margaret Wright’s analytical hidden-line removal and 2D contours are part of the commercial GraphiC Professional package (available on my website, jamesrome.com), so the 3D C engine is not in the free public repo.

However, the Makie vector backend for all 2D curves, lines, scatter markers, and multi-series plots is completely functional in the free repo!

How to test it with Makie

  1. Update the package in your Julia REPL (press ]):
text

pkg> update GraphiC

  1. Because GraphiCMakieExt is a Julia 1.9+ package extension, Julia loads it when both Makie and GraphiC are loaded in your session:
julia

using Makie, GraphiC
import GraphiC: graphic_makie
# Tell Makie to use GraphiC for vector output
graphic_makie()

# 2D multi-series lines and scatter
x = range(0.0, 10.0, length=100)
fig, ax, plt = lines(x, sin.(x); color=:blue, linewidth=2.0)
scatter!(ax, [2.0, 4.0, 6.0, 8.0], [0.91, -0.76, -0.28, 0.99]; color=:red, markersize=8)
# Generates a crisp, lightweight vector SVG:
save(“makie_vector.svg”, fig)

(If you are on an Apple Silicon Mac, the 2D Community libgraphic.dylib is bundled right in the repo’s lib/ directory so it works with zero setup. If you are on Linux or Windows, you can grab the free 2D Community package from jamesrome.com to compile the C library for your platform).

Give update GraphiC a try with the 2D example above and let me know how it works for you!

What I updated in the repo:

  • README.md: Updated to explicitly clarify that the free repo provides full 2D lines, scatter, bar charts, and vector SVG output, while 3D perspective surface meshes and contouring require GraphiC Professional.
  • Pushed commit 4bc1d56 to github.com/jimrome/GraphiC.jl.