VegaLite add line manually?

dfc_single |> @filter(_.gender ∈ ["Male", "Female"]) |>

@vlplot(
    :bar,
    width = 700, 
    y={
        "count()",
        axis={title="Gender fraction"},
        stack=:normalize
    },
    x="state",
    color = :gender,
)

produces:

which is pretty nice, now, I want to just add a horizontal line in ad-hoc fashion to denote total mean fraction, it is possible in vegalite (probably with :rule?)

Maybe:

+
@vlplot(
    mark={
        :rule,
        color="red"
    },
    x={"state:q", aggregate="average"}
)

But this may produce two lines, one for male and one for female.

Maybe like this:

@vlplot() +
    @vlplot(
        :bar,
        width = 700, 
        y={
            "count()",
            axis={title="Gender fraction"},
            stack=:normalize
        },
        x="state",
        color = :gender,
    ) +
    @vlplot(
        mark={:rule, color=:red},
        data={values=[{ref=0.4}]},
        y="ref:q"
    )

I think this will hopefully get a little easier in the future, see here.

@davidanthoff Do you know how to make it work with column and row?

dataset("cars") |>
@vlplot() +
@vlplot(:point, x = :Horsepower, y = :Miles_per_Gallon, column = :Origin,) +
@vlplot(mark = {:rule, color = :red}, data = {values = [{ref = 10}]}, y = "ref:q")

ignores column: https://vega.github.io/editor/#/url/vega-lite/N4KABGBEA2CGCeBTATpAXGA2uCZS90kQDsBjAewBMBLYgc3TxwIkgugFcBbYx4SAGbVE0So0gB5ZNTq1IAXwA0zFpAAefQcNHiAEuWQBnRAAdyAdxQLlLQvE1CRYjJACy1aIkMB9Eym8A4rDQ0OS88ioQSpFQXLDIANbiZrQALpAq0QT4qiQUNPSa9hj8jjouyIgCkIpQqfB+4gCOHLDEqdSpsB0AbogKWaqU3bCaPcEcXoyY-JXVGACMAAzyALqDBJBxiZrsBuKVYrWQ9Y0VHJ4KmTirNlDDXZocyNDiD7AA9KTxhgB0AFaGMJXeRAA

@tkf I think you can generally not layer a spec that has a facet (which kind of makes sense). So what you need to do instead is put a facet operator into a top-level spec, which then has a child spec which is a layered spec.

Thanks! So this seems to work:

@vlplot(
    data = dataset("cars"),
    facet = {row = {field = :Origin, type = :nominal}},
    spec = {
        layer = [
            {
                mark = :point,
                encoding = {x = {field = :Horsepower}, y = {field = :Miles_per_Gallon}},
            },
            {
                mark = {type = :rule, color = :red},
                data = {values = [{ref = 10}]},
                encoding = {y = {field = :ref, type = :quantitative}},
            },
        ],
    }
)

Yes! Here is a version that uses some more shortcuts:

dataset("cars") |>
@vlplot(facet = {row = {field = :Origin, type = :nominal}}) + 
    (
        @vlplot() +
        @vlplot(:point, :Horsepower, :Miles_per_Gallon) +
        @vlplot(mark={:rule, color=:red}, data = {values = [{ref = 10}]}, y="ref:q")
    )

I don’t fully understand right now why this extra @vlplot() is needed as the first element for the layered sub-spec, but hey, it works :slight_smile:

I think there are really two things that we could do on the Julia side to make this easier: a) add support for the shorthand parsing to the row field, so that facet={row="Origin:n"} works. b) sort out the composition story… I’ll try to find time to look over some of the proposals we had on that.

1 Like

Yeah, I thought there might be a way to write it shortly. I agree it’d be great to consolidate Julia side shortcuts more.

thx for the discussion and examples, something like this would be useful: https://github.com/JuliaPlots/Plots.jl/issues/17

I think once they implement this properly in the underlying Vega-Lite library, it will look like this: @vlplot(:rule, y={datum=20}). Until then we’ll have to live with the @vlplot(:rule, data={values=[ref=20}]}, y="ref:q") workaround.

1 Like