Duplicate signal name - Concatenating vega-lite visualizations

Hi,

I am trying to vertically concatenating an array of vega-lite visualizations using vl.vconcat().

I am able to concatenating the visualizations horizontally using .hconcat or .concat.

However, the following error is thrown when I try to do it using .vconcat:

Error: Duplicate signal name: “height”

The notebook should be available here: https://observablehq.com/d/874c7797671f2548

Each visualization is generated using the following function:

function generateTimeline_B(datePicked) {
  const datePicked_place_sessions = place_sessions.filter(d => d.date == datePicked);
  const datePicked_interactions = interactions.filter(d => d.date == datePicked);

  const intersactions_mark = vl.markPoint()
    .data(datePicked_interactions)
    .encode(
      vl.x().fieldT("15min_bins").timeUnit("hoursminutes").title("Time of day")
        .scale({domain: [{hours: 0, minutes: 0}, {hours: 24, minutes: 0}]}),
      vl.size().count("15min_bins").title("Number of interactions").legend(null),
      vl.color().value("black"),
      vl.opacity().value(1),
    )
  
  const place_sessions_mark = vl.markBar({ height: 60})
    .data(datePicked_place_sessions)
    .encode(
      vl.order().fieldQ('startTime').sort('ascending'),
      vl.x().fieldQ("durationHours").title("Duration in hours").scale({ domain: [0, 24] }),
      vl.color().fieldN('placeId').scale({ range: kellyColors }).title('Place'), //.legend(null)
      vl.opacity().value(0.3)
    )
    
  return vl
    .layer(intersactions_mark, place_sessions_mark)
    .width(200)
    .height(60)
    .title(`Timeline_B for ${datePicked}`)
    .view({stroke: null})
}

Then a visualization is generated for each unique date in the data and concatenated:

{
  // Find the unique dates from both datasets
  const uniqueDates = Array.from(new Set([
    ...place_sessions.map(d => d.date),
    ...interactions.map(d => d.date),
  ])).sort();

  // Generate the Vega-Lite specifications for each unique date
  const visualizations = uniqueDates.map(datePicked => generateTimeline_B(datePicked));

  // Concatenate the visualizations using vl.vconcat
  const combinedVisualizations = vl
    .vconcat(...visualizations)
    .config({ concat: { spacing: 5 }});

  // Display the combined visualizations
  return combinedVisualizations.render();
}

I think you might be running into a bug. Even after removing all height declarations I can still see two height signals in the generated spec. They might be intrinsic to the marks?

1 Like

Thank you very much for your response :slightly_smiling_face:

As you suggested, the issue is likely intrinsic to the vl.markBar. I found that removing the markBar layer resolved the error.

In addition, adding a y channel to the markBar encoding prevented the error - not a pretty fix, and as I am not very experienced in vega-lite and observable notebook, I do not entirely understand how it resolved the issue.

Unfortunately I’m not really familiar with vega-lite either. You could perhaps call .toSpec() instead of .render() to get a better idea of what’s been constructed internally.

Using my (experimental) table inspector might make it easier to review the spec:

import {asTable} from "3cf8dc57cdc0619f"
{
  // ...

  // Display the combined visualizations
  return asTable(combinedVisualizations.title("Timelines (B)").toSpec())
}