Makie plot specification?

I have a package, call it MyModels.jl, that needs to be light and fast, used mostly in backend tools that don’t want any visualization stuff in their dependencies. The package implements some mathematical models. In some use cases, we need to plot the results of those models, and how each model should be plotted is very much custom for that model. Right now, we have a separate package, MyModelsPlots.jl, that adds on the plotting functionality. Downstream users that want visualization can add this package to their projects. That works, but keeping the two packages tied together is tedious.

I was wondering if there was (or maybe ought to be some day) a package to allow a package like MyModels.jl to specify how to construct its plots, but that doesn’t actually do any plotting or depend on all the heavy visualization backends. That is, maybe there’s a package that’s just how you tell Makie what you want plotted.

Here’s an example. Please ignore that this doesn’t look like the Makie interface; it’s more like pseudocode.

module MyModels

using MakieSpecification

# Let's define ModelA's structure and behavior.
struct ModelA
    ... # Whatever
end

# Here's how ModelA should be plotted.
function plot_model(m::ModelA)
    return MakieSpecification.PlotSpec(
        figure = MakieSpecification.FigureSpec(
            axes = [
                MakieSpecification.AxisSpec(
                    plots = [
                        MakieSpecification.LineSpec(m.t, m.x),
                    ],
                    xlabel = "Time",
                    ylabel = "Model A: x",
                ),
            ]
        )
    )
end

The end user would then just do something like this:

using MyModels
import GLMakie

a = MyModels.ModelA()
# Do something with the model.
# ...

# Let's get the plot specification for the model and let GLMakie actually realize the plot.
GLMakie.plot(MyModels.plot_model(a))

Just to be super clear here, the key is that the same lightweight package that defines the structure and functionality would also describe how it is to be plotted, without it depending on the code that does the plotting. It would only depend on a plot specification package of some kind. This would let light users who don’t need plots to skip those dependencies but users who want them could have them without having a whole separate codebase to try to use/update in parallel.

Does this exist? Could it? Should it?

One could imagine some sort of Dict interface to the SpecApi that Makie already has. But nowadays it’s much easier to take on a weak dependency in this case. Then you can write your code with Makie’s full API, don’t have to write a separate package really, and users don’t pay the cost unless Makie is installed explicitly.

it doesn’t. But the correct way to achieve the same functionality is to use Extention mechanism of Pkg.jl: 5. Creating Packages · Pkg.jl

Yeah it doesn’t exist yet, but was planned for Plot serialization and dependency free recipes (which I agree isn’t as much needed anymore with extensions).
If you really want this, I encourage you to prototype a Dict based, easy to serialize version of the plotspec, with proper translation functions in a package with:

dict_to_spec(spec::Dict)::PlotSpec
spec_to_dict(spec::PlotSpec)::Dict

Thanks, all! It sounds like I have some things here to look into. I didn’t know about the SpecApi, so that seems like the place for me to start. I’ll come back to this thread with my ideas to see if they’re useful.