observablehq / plot

A concise API for exploratory data visualization implementing a layered grammar of graphics
https://observablehq.com/plot/
ISC License
4.38k stars 175 forks source link

Allow stroke-dasharray to be a channel? #380

Open ericemc3 opened 3 years ago

ericemc3 commented 3 years ago

Similar to the vl.strokedash() channel in vega-lite, this channel could be used to display, for example, estimated values as dotted lines, i.e. depending on an indicator column in the dataset:

image image

Note: a stroke-width channel would also prove useful...

PS: Plot is a great library, very intellectually stimulating, and the 21 beautifully written articles in the https://observablehq.com/collection/@observablehq/plot collection should be read by all data scientists!

mbostock commented 3 years ago

There is already a strokeDasharray option. See this example:

https://github.com/observablehq/plot/blob/main/test/plots/covid-ihme-projected-deaths.js

It could be made a channel I suppose, but in practice I think it is usually better to have two marks.

Fil commented 2 years ago

Here's a common use-case where the user would want the constant to be a channel (cc @espinielli):

textAnchor: d => d.properties.city === "Moscow" ? "end" : "start",

yurivish commented 2 years ago

I had the same case with textAnchor here and used two marks after trying one and learning that it wasn’t a channel.

harrislapiroff commented 1 year ago

I ran into this issue earlier this week in this notebook with two lines that were the same type of data, but one is a "current" system and one is a "proposed" system. I did accomplish this using two marks for each set of data,

    Plot.line(scenarios, {
      filter: d => d.system === 'proposed',
      stroke: PROFIT_COLOR,
      y: 'bidaProfit',
      x: 'attendees',
      fx: 'musicians',
      strokeWidth: 3,
    }),
    Plot.line(scenarios, {
      filter: d => d.system === 'current',
      stroke: PROFIT_COLOR,
      y: 'bidaProfit',
      x: 'attendees',
      fx: 'musicians',
      strokeWidth: 3,
      strokeDasharray: '2 10',
    }),

but I think it would have been more elegant if I had been able to use one:

    Plot.line(scenarios, {
      stroke: PROFIT_COLOR,
      y: 'bidaProfit',
      x: 'attendees',
      fx: 'musicians',
      strokeWidth: 3,
      strokeDasharray: d => d.system === 'current' ? '2 10' : null
    })