livebook-dev / vega_lite

Elixir bindings for Vega-Lite

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Limitations in rendering layers + repeat?

dognotdog opened this issue · comments

I've got the following scenario: I want to render two disjoint layers with different x,y values on top of each other. The first is a list of vectors from a tensor, the second is different sets of reference data.

No matter how I try to arrange Vl.layers() or Vl.repeat(), VegaLite will not render. Now this might be a Vega-Lite limitation, but it isn't clear from the docs.

This (just the repeat) works

{times, _nsamples} = Nx.shape(signal_tensor)
samples = for i <- 0..(times-1), do: {"#{:io_lib.format "s~3..0B", [i]}", Nx.to_flat_list(signal_tensor[i])}
y_names = for {name, _data} <- samples, do: name
plot_data = [x: x_data] ++ samples
Vl.new(width: 700, height: 400, autosize: [type: "fit", contains: "content"])
    |> Vl.encode(:size, value: 1)
    |> Vl.data_from_series(plot_data)
    |> Vl.transform(filter: [field: "x", range: plot_range])
    |> Vl.repeat(
      [layer: y_names],
      Vl.new()
        |> Vl.mark(:line, clip: true)
        |> Vl.encode_field(:x, "x", type: :quantitative, scale: [domain: plot_range])
        |> Vl.encode_repeat(:y, :layer, type: :quantitative, scale: [zero: false], title: "signals")
        |> Vl.encode(:color, type: :nominal, datum: [repeat: :layer], scale: [scheme: "turbo"])
        |> Vl.encode(:opacity, value: 0.5)
    )

Now what I'd like to do is plot a different signal on the same graph, but I cannot find a way to add Vl.layers() in a meaningful way.

Any ideas?

@dognotdog I would start by picking the closest graph you need from their Gallery and converting them to the spec and then modifying it: https://vega.github.io/vega-lite/examples/ - which graph resembles the closest that you need?

Hey @dognotdog, you can use repeat on the top level, and use a layered specification for the repetition. Not sure if this matches your case, but hopefully gives a better idea:

# Source: https://vega.github.io/vega-lite/docs/layer.html#combined-scales-and-guides
# ^ modified 

Vl.new()
|> Vl.data_from_url("https://vega.github.io/editor/data/weather.csv")
|> Vl.transform(filter: "datum.location == 'Seattle'")
|> Vl.repeat(
  ["temp_max", "temp_min"],
  Vl.new(width: 400, height: 300)
  |> Vl.encode_field(:x, "date", time_unit: :month, axis: [format: "%b", title: nil])
  |> Vl.layers([
    Vl.new()
    |> Vl.mark(:line, interpolate: :monotone, stroke: "dodgerblue")
    |> Vl.encode_repeat(:y, :repeat, aggregate: :average),
    Vl.new()
    |> Vl.mark(:line, interpolate: :monotone, stroke: "tomato")
    |> Vl.encode_field(:y, "precipitation", aggregate: :average)
  ])
  |> Vl.resolve(:scale, x: :independent, y: :independent)
)

visualization (1)

@jonatanklosko thanks that plot shows a few interesting things to try (like the Vl.resolve) that might be the cause of the hickup!

@dognotdog there doesn't seem to be any actual issue, and such limitations would rather lay on the Vega-Lite side, so I'm going to close this for now. Feel free to reopen if you have further questions :)