Plotting multiple datasets in the same chart in VegaLite

Is it possible to plot multiple datasets in the same VegaLite chart without merging them beforehand? I thought “adding” two @vlplot statements like this would work, but it only displays the sp500 data.

using VegaLite, Query, VegaDatasets

goog = dataset("stocks") |> @filter(_.symbol == "GOOG")
sp500 = dataset("sp500")

@vlplot(mark={:line, color=:red}, data=goog, x="date:t", y=:price) +
    @vlplot(mark={:line, color=:black}, data=sp500, x="date:t", y=:price)

@vlplot() + @vlplot(mark={:line, color=:red}, data=goog, x="date:t", y=:price) + @vlplot(mark={:line, color=:black}, data=sp500, x="date:t", y=:price)

see examples:

http://fredo-dedup.github.io/VegaLite.jl/stable/examples/examples_error_bars_bands.html

Thanks! Now that you bring it up, I did notice that bizarre empty @vlplot() statement earlier when I browsed the examples, but I didn’t connect it with this. Can you explain what it does?

I really need to write the doc for composite plots :slight_smile: But, I’m still not a 100% sure I got the API right, so maybe some feedback first would be great.

The logic here is the following: the first @vlplot() creates an empty spec. The + operator then does the following: it adds the thing on the right hand side inside a layer elment to the thing on the left hand side. In this case here, the second and the third @vlplot things become entries in the layer element of the spec created by the first empty @vlplot() call.

Now that I’m thinking about this, I can’t fully understand why I didn’t just make this work without this first @vlplot() call though…

1 Like

I don’t see any issues here.

The first empty @vlplot() doesn’t seem “bizarre” to me. Maybe it is just not intuitive in the special example where @vlplot() seems to be an empty call.

If you look at it as the initial call to set all defaults for the overall setting of the image it is very intuitive. Example:

using VegaLite, Query, VegaDatasets

goog = dataset("stocks") |> @filter(_.symbol == "GOOG")
sp500 = dataset("sp500")
msft = dataset("stocks") |> @filter(_.symbol == "MSFT")

@vlplot(width=400,height=400) +
@vlplot(mark={:line, color=:red}, data=goog, x="date:t", y=:price) +
@vlplot(mark={:line, color=:black}, data=sp500, x="date:t", y=:price) +
@vlplot(mark={:line, color=:green}, data=msft, x="date:t", y=:price)

visualization

2 Likes

How do one get a legend in the above example by oheil?

And how do I get a grouped bar chart with the same data as above? All the examples I have seen about grouped bar charts and normalized bar charts work with differentiating data in the same field.

Adding a legend to the plot is not straight forward for me.

This is my solution for reproducing the plot with legend:

using VegaLite, Query, VegaDatasets
using DataFrames

goog = dataset("stocks") |> @filter(_.symbol == "GOOG")
sp500 = DataFrame(dataset("sp500"))
sp500[:symbol]="sp500"
msft = dataset("stocks") |> @filter(_.symbol == "MSFT")

@vlplot(width=400,height=400, color={field="symbol",scale={range=["black","red","green"]}}) +
@vlplot(mark={:line,color=:red}, data=goog, x="date:t", y=:price) +
@vlplot(mark={:line,color=:black}, data=sp500, x="date:t", y=:price) +
@vlplot(mark={:line,color=:green}, data=msft, x="date:t", y=:price)

The colors in the mark specification are ignored and superseded by the color range in the scale definition.

As far as I understand the vega-lite documentation it seems to be not possible to create grouped bar charts using Layering Views (created in VegaLite.jl with the + -Operator and documented under Layered Plots).
For grouped bar charts you have to use vega-lite Faceting which is, as you say, done by “differentiating data in the same field”, see vega-lite grouped bar chart.

With the data above this could be achieved with:

alldata=vcat(sp500,DataFrame(dataset("stocks")))

@vlplot(:bar, transform=[{filter={field="symbol","oneOf"=["sp500","GOOG","MSFT"]}}],data=alldata, enc={column="date:n",x={field="symbol",type="nominal",axis={title=""}}, y=:price}, color=:symbol)

.

2 Likes