vega-lite icon indicating copy to clipboard operation
vega-lite copied to clipboard

'Duplicate signal name' error for shared param across views

Open cjnygard opened this issue 4 years ago • 7 comments

When using repeat to layer multiple fields, one is unable to use hover to implement any interaction. An error is shown Error: Duplicate signal name: "sel1_tuple"

See https://observablehq.com/@cjnygard/vega-lite-bug for implementation (you can play with the flags in the plot4() function to true different combinations of hover, repeat, and facet. It's clearly related to the repeat, as shown in the below generated JSON (generated from the page above).

{
  "facet": {
    "column": {
      "field": "name"
    }
  },
  "spec": {
    "repeat": {
      "layer": [
//        "y1",    // Uncomment this to trigger bug
        "y2"
      ]
    },
    "spec": {
      "layer": [
        {
          "mark": {
            "type": "line",
            "interpolate": "monotone"
          },
          "encoding": {
            "x": {
              "field": "x",
              "type": "quantitative"
            },
            "y": {
              "field": {
                "repeat": "layer"
              },
              "type": "quantitative"
            },
            "color": {
              "datum": {
                "repeat": "layer"
              },
              "legend": {
                "title": "Legend"
              }
            }
          }
        },
        {
          "mark": {
            "type": "circle"
          },
          "encoding": {
            "x": {
              "field": "x",
              "type": "quantitative"
            },
            "y": {
              "field": {
                "repeat": "layer"
              },
              "type": "quantitative"
            },
            "color": {
              "datum": {
                "repeat": "layer"
              },
              "legend": {
                "title": "Legend"
              }
            },
            "opacity": {
              "condition": {
                "test": {
                  "selection": "sel1"
                },
                "value": 1
              },
              "value": 0
            }
          },
          "selection": {
            "sel1": {
              "type": "single",
              "encodings": [
                "y"
              ],
              "on": "mouseover",
              "nearest": true,
              "empty": "none"
            }
          }
        }
      ],
      "width": 350,
      "height": 200
    }
  },
  "data": {
    "values": [
      {
        "name": "foo",
        "x": 1,
        "y1": 1,
        "y2": 21
      },
      {
        "name": "foo",
        "x": 2,
        "y1": 2,
        "y2": 22
      },
      {
        "name": "foo",
        "x": 3,
        "y1": 3,
        "y2": 23
      },
      {
        "name": "bar",
        "x": 4,
        "y1": 10,
        "y2": 31
      },
      {
        "name": "bar",
        "x": 5,
        "y1": 11,
        "y2": 32
      },
      {
        "name": "bar",
        "x": 6,
        "y1": 12,
        "y2": 33
      }
    ]
  }
}

cjnygard avatar Sep 22 '20 03:09 cjnygard

Thanks for the bug report. To isolate the issue, can you try to simplify the spec to a minimal spec?

domoritz avatar Sep 22 '20 05:09 domoritz

It already is. Uncomment the line, it will break. Comment the line, it will not break. It has two lines, each with three points, so that you can see the hover in action reliably. It has one x coord, and two y coords, so you can actually see the difference when repeating for two fields. See the Observablehq page linked above if you want to play with layer/facet/repeat options.

cjnygard avatar Sep 25 '20 02:09 cjnygard

Could you do me a favor and try to reproduce the issue with just layer and no repeat? It would help us isolate the problem.

domoritz avatar Sep 25 '20 03:09 domoritz

I cannot. It works fine without repeat.

{
  "facet": {
    "column": {
      "field": "name"
    }
  },
  "spec": {
    "layer": [
      {
        "mark": {
          "type": "line",
          "interpolate": "monotone"
        },
        "encoding": {
          "x": {
            "field": "x",
            "type": "quantitative"
          },
          "y": {
            "field": "y1",
            "type": "quantitative"
          },
          "color": {
            "datum": "y1",
            "legend": {
              "title": "Legend"
            }
          }
        }
      },
      {
        "mark": {
          "type": "circle"
        },
        "encoding": {
          "x": {
            "field": "x",
            "type": "quantitative"
          },
          "y": {
            "field": "y1",
            "type": "quantitative"
          },
          "color": {
            "datum": "y1",
            "legend": {
              "title": "Legend"
            }
          },
          "opacity": {
            "condition": {
              "test": {
                "selection": "sel1"
              },
              "value": 1
            },
            "value": 0
          }
        },
        "selection": {
          "sel1": {
            "type": "single",
            "encodings": [
              "y"
            ],
            "on": "mouseover",
            "nearest": true,
            "empty": "none"
          }
        }
      }
    ],
    "width": 350,
    "height": 200
  },
  "data": {
    "values": [
      {
        "name": "foo",
        "x": 1,
        "y1": 1,
        "y2": 21
      },
      {
        "name": "foo",
        "x": 2,
        "y1": 2,
        "y2": 22
      },
      {
        "name": "foo",
        "x": 3,
        "y1": 3,
        "y2": 23
      },
      {
        "name": "bar",
        "x": 4,
        "y1": 10,
        "y2": 31
      },
      {
        "name": "bar",
        "x": 5,
        "y1": 11,
        "y2": 32
      },
      {
        "name": "bar",
        "x": 6,
        "y1": 12,
        "y2": 33
      }
    ]
  }
}

cjnygard avatar Sep 28 '20 03:09 cjnygard

Hello, do you have any solution to this issue ? I'm trying to have a tooltip like this while using the repeat feature but if I put the rule layer inside the spec I have the same error. I also tried to put the rule layer on top level of the object in the layer property but it seems ignored if I use the repeat feature...

If you have any hint that would be appreciated 😄 thanks !

wmarques avatar Jan 08 '21 17:01 wmarques

I haven't looked into this issue yet. To make debugging easier it would be awesome if you could create a minimal example.

domoritz avatar Jan 08 '21 17:01 domoritz

I'm able to replicate this when we add params to top-level for multi-view charts

{

  "params": [{"name": "selection", "select": {"type": "point"}}],
  "data": {"url": "data/cars.json"},
  "layer": [
    {
      "mark": {"type": "point", "filled": true},
      "encoding": {
        "x": {"field": "Horsepower", "type": "quantitative"},
        "y": {"field": "Acceleration", "type": "quantitative"}
      }
    },
    {
      "transform": [{"filter": {"param": "selection"}}],
      "mark": {"type": "point", "filled": true},
      "encoding": {
        "x": {"field": "Horsepower", "type": "quantitative"},
        "y": {"field": "Acceleration", "type": "quantitative"}
      }
    }
  ]
}

kanitw avatar Mar 11 '22 19:03 kanitw

Hard to believe this bug has been open for over two years and is now a P2. As from days spent trying to work around it, it reduces both primary means of dealing with data complexity, faceting and repeats, as no longer supporting direct interaction. I guess this yields a "Graphenberg" state, you can see your data, or you can interact with it, but you can't do both :-(

jw5 avatar Oct 04 '22 07:10 jw5

The reply from @kanitw with top-level defined params and a layered chart can be resolved using views within params in combination with a name definition on a single chart object within the layer: Open the Chart in the Vega Editor

Status of a chart with a:

  1. repeat operator & params within the spec: Open the Chart in the Vega Editor
  2. repeat operator & params top-level: Open the Chart in the Vega Editor
  3. repeat operator & params top-level using a views attribute and name: Open the Chart in the Vega Editor
  4. repeat operator on a layer & params on the first object within layer: Open the Chart in the Vega Editor (slow!)
  5. repeat operator on a layer & params top-level: Open the Chart in the Vega Editor
  6. repeat operator on a layer & params top-level using a views attribute & name on the first object within layer: Open the Chart in the Vega Editor (slow!)

The following issue is also related to the repeat operator on a layer with params top-level using a views attribute & name on the first object within layer: https://github.com/vega/vega-lite/issues/8348, but there is still another issue with brush not resolving properly.

mattijn avatar Oct 04 '22 11:10 mattijn

First, thank you very much for the timely and informative answer with several examples. Alas, I've spent a day trying, but my attempts to generalize your solution and apply it to my particular charts have not met with much success. I just can't seem to get a faceted repeated layered specification to work.

Working simple facet(repeat(layer)) without interaction: Open the Chart in the Vega Editor

Broken attempt to add interaction version 1 of 10: Open the Chart in the Vega Editor

Note: These are not meant to be great graphics, just the smallest perturbation to your examples that reflected the nesting structure I need for my data (multiple factor columns and repeated metric fields).

Hopefully there is a known workaround for this version of the problem.

Thanks, Jim

jw5 avatar Oct 07 '22 05:10 jw5

Two things:

  1. I was not able to render a chart with a name-defined layer (here below FOO) in combination with a repeat and facet operator (without parameters defined).

The following Vega-Lite spec, Open the Chart in the Vega Editor:

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": {"url": "data/weather.csv"},
  "facet": {"field": "location", "type": "nominal"},
  "spec": {
    "repeat": {"layer": ["temp_max", "precipitation", "wind"]},
    "spec": {
      "layer": [
        {
          "name": "FOO",
          "mark": "rule",
          "encoding": {
            "x": {"field": "date", "timeUnit": "month"},
            "color": {"value": "black"},
            "opacity": {"value": 1}
          }
        },
        {
          "mark": {"type": "line", "point": false},
          "encoding": {
            "x": {"field": "date", "timeUnit": "month"},
            "y": {"field": {"repeat": "layer"}, "aggregate": "mean"},
            "color": {"datum": {"repeat": "layer"}, "type": "nominal"}
          }
        }
      ]
    }
  }
}

Result in the following error:

Duplicate data set name: "FOO_marks".

If you remove "name": "FOO" then the chart renders, but I think you need this name to set a spefic view in the params to avoid the duplicate signal name error (?). I do not know an approach how to define or refer to a unique name, maybe using an expr?


  1. A workaround.

You can use a fold-transform on the columns that you like to layer and use the key-value output instead of the repeat operator.

As such, Open the Chart in the Vega Editor:

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": {"url": "data/weather.csv"},
  "transform": [{"fold": ["temp_max", "precipitation", "wind"]}],
  "facet": {"field": "location", "type": "nominal"},
  "params": [
    {
      "name": "HIGHLIGHT",
      "select": {
        "type": "point",
        "nearest": true,
        "on": "mouseover",
        "clear": "mouseout",
        "encodings": ["x"]
      },
      "views": ["CHART_0"]
    }
  ],
  "spec": {
    "layer": [
      {
        "name": "CHART_0",
        "mark": "rule",
        "encoding": {
          "x": {"field": "date", "timeUnit": "month"},
          "color": {"value": "black"},
          "opacity": {
            "condition": {"param": "HIGHLIGHT", "empty": false, "value": 1},
            "value": 0
          }
        }
      },
      {
        "mark": {"type": "line", "point": true},
        "encoding": {
          "x": {"field": "date", "timeUnit": "month"},
          "y": {"field": "value", "aggregate": "mean", "title":"Mean of temp_max, precipitation, wind"},
          "color": {"field": "key", "type": "nominal", "title":null}
        }
      }
    ]
  }
}

image


And a bonus, using row/column facetting and a shared rule: Open the Chart in the Vega Editor image

mattijn avatar Oct 07 '22 08:10 mattijn

  1. I tried several variations to solve 1. Direct use of expr, field etc result in duplicate object... That suggests that the duplication occurs before evaluation. So then I tried moving it under evaluation. That doesn't fail directly, it parses and executes to no effect, which suggests the mapping to the signal is broken.

Open the Chart in the Vega Editor

  1. While the conversion from wide to long form (R GGplot vernacular) works well for smaller data sets. I'm pushing 100K+ records with perhaps 5-10 dimensions and 10+ metrics. My concern is that doing a fold transform will increase the record count 10X and carry lots of duplicate dimension information thus resulting in increased memory requirements in the browser. Still, it may be a performance hit I'll have to take for more complex charts.

Thanks, Jim

jw5 avatar Oct 07 '22 17:10 jw5

  1. I also tried encoding name. Its intuitive, but it is not in the list of https://vega.github.io/vega-lite/docs/encoding.html, so probably silently ignored (cc @domoritz).
  2. Yes, with that datasize please aggregate before rendering. We have good experiences with duckdb in combination with vega-lite.

mattijn avatar Oct 07 '22 19:10 mattijn

  1. I tried unsuccessfully to locate the explicit definition of "name" by searching the vega-lite site. It is listed in the parameter definition, but I don't recall seeing it elsewhere?

  2. That is the significantly aggregated data set, it starts at O(2T) records ;-)

Thanks, Jim

On Fri, Oct 7, 2022 at 12:36 PM Mattijn van Hoek @.***> wrote:

  1. I also tried encoding name. Its intuitive, but it is not in the list of https://vega.github.io/vega-lite/docs/encoding.html, so probably silently ignored (cc @domoritz https://github.com/domoritz).
  2. Yes, with that datasize please aggregate before rendering. We have good experiences with duckdb in combination with vega-lite.

— Reply to this email directly, view it on GitHub https://github.com/vega/vega-lite/issues/6890#issuecomment-1272023942, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC4LRFH44URNGTL3F3VOEOLWCB3UVANCNFSM4RVI7XHQ . You are receiving this because you commented.Message ID: @.***>

jw5 avatar Oct 07 '22 20:10 jw5

bump

aaroncsolomon avatar Mar 13 '23 01:03 aaroncsolomon