Author Archives: David Anthoff

VegaLite.jl v2.1 released

By: David Anthoff

Re-posted from: https://www.queryverse.org//2020/04/06/vegalite-v2.1/

I just released VegaLite.jl v2.1. While this release just tracks what is happening upstream in the Vega-Lite project, there are some really nice feature additions.

For all the details you can read through the release notes of Vega-Lite:

I’ll use the rest of this post to highlight a few key new features.

Arc marks

Vega-Lite now supports a new arc mark that makes it easy to create pie, donut and radial charts:

arc mark

For more information, you can read the original Vega-Lite documentation and you can look at a number of Julia examples.

Datum in encoding

The new support for datum in encodings makes it easy to add for example a rule at a given point to a figure.

An example that adds a horizontal rule to a figure is this:

using VegaLite, VegaDatasets

dataset("stocks") |>
@vlplot() +
@vlplot(:line, "date:t", :price, color=:symbol) +
@vlplot(mark={:rule, strokeDash=[2,2], size=2}, y={datum=300})

figure

Note how the y channel here is given a datum, that is a value from the underlying price domain.

For temporal values this has especially nice syntax:

using VegaLite, VegaDatasets

dataset("stocks") |>
@vlplot() +
@vlplot(:line, "date:t", :price, color=:symbol) +
@vlplot(mark={:rule, strokeDash=[2,2], size=2}, x={datum={year=2006}})

figure

Note how we can set a value for a specific year here.

Angle channel for point and text marks

A new angle channel makes it easy to create for example the following wind vector map:

figure

You can find the Julia code for this example in the documentation.

Conclusion

This release was literally zero work on the Julia side of things, all the thanks for these new features should go to the awesome Vega-Lite team that keeps adding new functionality at an amazing speed!

VegaLite.jl v2.0.0 released

By: David Anthoff

Re-posted from: https://www.queryverse.org//2020/03/11/vegalite-v2.0.0/

We released VegaLite.jl v2.0 a couple of days ago. This new version brings a lot of new features along! I’ll try to walk you through some of them in this blog post.

For those of you not familiar with the package: VegaLite.jl is a powerful plotting package for Julia.

Vega-Lite 4

We updated the Julia package to use the latest version of the underlying JavaScript library, Vega-Lite 4. This brings a ton of new features to the table. You can take a look at a detailed description of all these updates by looking at the release notes for all the Vega-Lite versions we now incorporate:

I encourage you to take a look at these release notes, they have examples for each new feature and give a good overview of what is happening in the underlying library. There is a lot of good stuff (regression, loess, density and quantile transforms, a strokeDash encoding channel, lots of new interactive stuff and a ton of other features)!

Support for inline data

We now support inline data, i.e. you can now create a plot from vectors of data directly, without the need to pass a tabular data structure like DataFrame to the plot function. The following example plots a scatter plot of two vectors of random numbers:

using VegaLite

a_vector = rand(10)

@vlplot(:point, x=rand(10), y=a_vector)

You can also pass vectors inside a composite value:

using VegaLite 

@vlplot(:line, x={1:10, title="Timestep"}, y=rand(10))

Support for positional x and y encodings

The values for the x and y encoding channel can now be passed as positional arguments, thus further reducing the amount of code required for common plots.

In particular, the second positional argument is now interpreted as the x channel, and the third positional argument as the y channel.

A simple example that uses some tabular data is this:

using VegaLite, VegaDatasets

dataset("cars") |> @vlplot(:point, :Acceleration, :Miles_per_Gallon)

The combination of positional arguments and inline data makes the code for a simple scatter plot of two vectors really concise:

using VegaLite

a = rand(10)
b = rand(10)

@vlplot(:point, a, b)

Save plots as HTML files

You can now save a plot directly as a HTML file:

using VegaLite

@vlplot(:point, rand(10), rand(10)) |> save("figure.html")

These HTML files are self contained, and are especially useful for interactive charts (which will fully work if someone opens the generated HTML file in a web browser).

Much better support for Vega specs

The package now exports a new @vgplot macro. It works exactly like @vlplot, except that you can use it to create Vega plots. Vega is the lower-level plotting library that Vega-Lite uses under the hood. It is more verbose than Vega-Lite, but gives you much more control over the types of plots you can create. Take a look at the Vega examples to get a sense.

Better Juno integration

Interactive plots should now work properly in Juno.

Convert plots into Julia code (experimental)

You can now take a plot object and call a function to get some Julia code that would re-create exactly that plot object. Here is a simple example:

using VegaLite, VegaDatasets

p = dataset("cars") |> @vlplot(:point, :Acceleration, :Miles_per_Gallon)

VegaLite.printrepr(stdout, p)

This will output:

@vlplot(mark="point",encoding={x={field="Acceleration"},y={field="Miles_per_Gallon"}})

This standalone example is probably not very useful, but this functionality can be very convenient if you obtain the plot from some other source.

For example, here is an example where you copy a Vega-Lite JSON example and convert it into an equivalent Julia code representation:

using VegaLite

p = vl"""
{
    "mark": "point",
    "encoding": {
        "x": {
            "field": "Miles_per_Gallon"
        },
        "y": {
            "field": "Acceleration"
        }
    }
}
"""

VegaLite.printrepr(stdout, p)

This also outputs the Julia code that would create this spec:

@vlplot(encoding={x={field="Miles_per_Gallon"},y={field="Acceleration"}},mark="point")

Another scenario is that you load a Vega-Lite spec from disc and directly convert it into Julia code:

using VegaLite

VegaLite.printrepr(stdout, load("figure.vegalite"))

Or maybe you used DataVoyager.jl to interactively create a plot and now want to include some code that creates that same figure, but in a non-interactive way:

using DataVoyager, VegaDatasets

# Run Voyager

w = dataset("cars") |> Voyager()

# At this point you would interactively create your plot and proceed once you are done with that

# Extract the plot from the UI
p = w[]

# Convert the interactively created plot into Julia code
VegaLite.printrepr(stdout, p)

New examples

We have a ton of new examples, both for Vega and Vega-Lite plots in the documentation, check them out here!

New expert APIs (experimental)

We now also export a purely non-macro based API. The two functions for that are vlplot and vgplot. Normal users are encouraged to continue to use the @vlplot and @vgplot macros, these new functions are mostly meant for some special situations where other packages can’t use the macro versions of these calls.

We also export new macros and functions called @vlfrag, @vgfrag, vlfrag and vgfrag. These allow you to create spec fragments and then pass these to the main level @vlplot, @vgplot, vlplot and vgplot macros and functions.

For example, in this example I break up the call to @vlplot into two calls by using the @vlfrag macro:

using VegaLite, VegaDatasets

x_frag = @vlfrag(:Miles_per_Gallon, title="Custom title")

dataset("cars") |> @vlplot(:point, x=x_frag)

We again discourage use of this feature in normal user code, this is another feature that is probably most useful for package authors that want to make use of VegaLite.jl.

Bug fixes and performance

There are a ton of bug fixes and performance improvements in this version:

  • We handle inline data much more efficiently
  • We auto-encode encoding types in sub specs
  • We properly apply shorthands in sub specs

Thanks

This release had a lot of folks contributing, I in particular want to thank oheil, mcmcgrath13 and tkf for their help!

Announcing ElectronDisplay.jl

By: David Anthoff

Re-posted from: https://www.queryverse.org//2019/02/13/electrondisplay/

ElectronDisplay.jl is a package that provides a simple UI based on Electron for displaying plots and tabular data. It works with most plotting packages and almost all data structures that represent tabular data in the Julia ecosystem. The package is a core piece of the Queryverse.

Plot display

Anytime you load ElectronDisplay.jl via using ElectonDisplay, it automatically becomes the default display for you current Julia session. From that moment on, whenever you display a figure from any of the supported plotting packages, it will show up in a window that is managed by ElectronDisplay.jl. Any plotting package that hooks into the standard Julia multimedia I/O API will work with this setup, as long as it supports either the PNG or SVG format with its show method.

ElectronDisplay.jl provides more tightly integrated support for PlotlyJS.jl and VegaLite.jl: plots from both packages support a full range of interactive features inside the window that ElectronDisplay.jl opens for them.

Here is a simple example of how this works. Executing the following example code

julia> using VegaLite, VegaDatasets, ElectronDisplay

julia> dataset("cars") |> @vlplot(:point, x=:Acceleration, y=:Miles_per_Gallon, color=:Origin)

will open a window that displays this plot:

VegaLite.jl screenshot

Table display

Thanks to tks’s fantastic recent contribution, ElectronDisplay.jl now also has support for showing tabular data in a grid. To display a table in that way, you simply pass it to the electrondisplay function, and it will show in a new window.

The following example demonstrates how easy it is to display a DataFrame:

julia> using DataFrames, ElectronDisplay

julia> df = DataFrame(a=rand(100), b=rand(100), c=rand(100));

julia> electrondisplay(df)

The table view works with almost any tabular source, not just DataFrames.jl. For example, here we are showing the result of a Query.jl query directly in the grid, without ever materializing it into a DataFrame:

julia> using VegaDatasets, Query, ElectronDisplay

julia> dataset("cars") |>
       @filter(_.Origin=="USA") |>
       @select(-:Miles_per_Gallon) |>
       electrondisplay

And the results are shown in a window like this:

Grid screenshot

The table display in ElectronDisplay.jl works for any source that either supports a show method for the application/vnd.dataresource+json MIME type, or implements the TableTraits.jl interface. Anything that iterates named tuples automatically is a TableTraits.jl source, so even packages that have never heard of either option might well work with ElectronDisplay.jl.

Summary

ElectronDisplay.jl is probably most useful for people that work directly in the Julia REPL and not in one of the more fully feature IDEs. It is also a very young package, and any help with the package would be most welcome! I have created a few issues with ideas for improvements, but I am sure there are many more. I think this could be a project where someone with web UI experience could really contribute significantly.