Version 2.0 of Plot

16 views
Skip to first unread message

Steve Nunez

unread,
May 9, 2022, 1:37:29 AM5/9/22
to lisp...@googlegroups.com

I mentioned that there is a new version of plot in development, and it seems like a good time to push it out. The version on the master branch should be considered deprecated. The new version uses the lessons learned from v1 and is more succinct and a better base to build on. The work-in-progress branch for version 2.0 has been in progress for a while and subject to a few caveats, is stable enough to use. Here’s a quick example of a plot of sin & cos:

 

;; Plot sin and cos

(defparameter x (linspace 0 (* 2 pi) 100))

(defparameter sin-cos `(:x   ,x

                        :sin ,(esin x)

                        :cos ,(ecos x)))

 

(vglt:defplot sin-cos-plot `(:mark :line

                             :data ,(vglt::multi-line-plot-data sin-cos) ;convert to vega-lite ‘long’ format

                             :encoding (:x (:field x :type "quantitative")

                                        :y (:field y :type "quantitative")

                                        :color (:field f :type "nominal"))))

 

(plot:plot-from-file (vglt:write-html sin-cos-plot)) ;display plot in configured browser

 

That’s a lot easier to specify than the alist version!

 

In addition to a plist style of plot specification, writing to streams is functional. There is the concept of a device, that is a plist specification the locations that the bits and pieces of a vega lite plot need to go to. For example if I wanted to write the above plot to a directory on my desktop and view it with Vega Desktop, I could do this:

 

(defparameter vgdsk '(:spec-loc #P"~/Desktop/plots/"))

(vglt:plot-to-device sin-cos-plot vgdsk)

 

Vega Desktop is deprecated, but still works. I find it a useful part of a plotting workflow because you can wrap the plotting:

 

(vglt:plot-to-device (defplot sin-cos-plot …)

    vgdsk)

 

and by ‘watching’ the plot from within Vega Desktop revaluating the form will immediately display the new results. I.e. fast, REPL style development loop.

 

What works, what doesn’t?

 

The plist style specification works, as does the writing to streams. You can, for example, write the different parts of a Vega Lite spec to different locations, e.g.:

 

(plot-to-device hp-mpg '(:spec-loc #P"~/Desktop/plots/"

                         :data-url "hp-mpg-data.json"

                         :data-loc #P"~/Desktop/plots/"))

 

See src/vglt/device.lisp for more examples. The function write-spec (plot.lisp) does all the heavy lifting. At the moment generic and pathname streams are supported, and others (gists, URL, etc) could be added easily. If someone wants gists, contact me; I have started some work on this but not checked it in.

 

What doesn’t work are the higher level functions found in examples.lisp. Well, they may work, but that idea turned out to be a dead-end. Vega-Lite is just too fussy and not very clean to put a higher level interface at that point. The architecture I have in mind at the moment looks like this (GoG means Grammar of Graphics):

 

 

 

Ultimately I envision creating plots similar to ggplot, using a lisp threading macro. You’ll start by specifying the basic aesthetics and data at the Lisp-Stat level using a grammar of graphics, then further on in the treading add back-end specific layers, like ‘hover’ or interactive graphics, which are specific to each backend (Plotly, Vega-Lite, etc). Another advantage of this architecture is that the backend layers shouldn’t have a dependency on Lisp-Stat; they will work with CL data structures. This means that they’ll be generally useful to the Lisp community, even for those that aren’t using Lisp-Stat and hopefully attract more contributors.

 

The display part has been thought through and there’s someone working on it, but for now we’ll continue to use the plot-from-file or plot-to-device.

 

The current plan is to stabilise the v2/wip branch:

 

  • Fix the problem Nathan discovered in time series plots
  • Detangle the helper functions from the VGLT package
  • Remove the dependencies on lisp-stat from VGLT

 

And then add a GG package in a v2/gg branch. Then we’ll add the functions for working with displays, similar to how Julia works before calling version 2.0 done.

 

As always, questions, comments and contributions are welcome.

Reply all
Reply to author
Forward
0 new messages