Legend and auto-colors for line plot

Hey all, observable newbie here.

I really like what I see so far but I cannot find a good example or anything in the documentation for the following:

    resize((width) => Plot.plot({
      title: "Output Power",
      x: {grid: true, type: "time", label: "Time", transform: (x) => new Date(x)},
      y: {grid: true, label: "Generated Power [Wh]"},
      marks: [
        Plot.lineY(powerlog, {x: "time", y: "power_ch1", title: "Ch1"}),
        Plot.lineY(powerlog, {x: "time", y: "power_ch2", title: "Ch2"}),
        Plot.lineY(powerlog, {x: "time", y: (row) => row['power_ch1'] + row['power_ch2'], title: "Total"})

How can I let observable give these three lineY plots distinct colors, and show a legend with the titles?

I found “strokes” with which I could manually set some colors, but I was hoping that such a stylistic question can be done automatically by the framework for me?


The same question applies to stacking of columnar data: Plot: Stacked bars / Observable | Observable

The example once again assumes one large vector of input data with categories to separate them. What if that is not the case - and instead the categories are separate columns?

You’re right that Plot is designed for so-called “tidy data” — long, not wide. Personally, in this situation I’d reshape the data before I pass it into Plot. (I’d also probably convert the time column to dates before passing it in, though that’s nice use of a transform you have in there.) But it’s also possible to make a legend “manually”, regardless of the shape of your data. Here are some examples:

Thank you! This unblocks me from creating the plots I want.

But I have to admit - from a data management POV this looks very backwards. I have neatly separated plots, now need to throw them together, only to let them be split up again - just to get a legend and auto generated colors… Am I alone in that thinking? For my purpose, it would be ideal if I could somehow manually associate a “stroke” value with the data set, such that it is interpreted as an ordinal value, and the line gets auto-colorized and included in the legend.

I see e.g. that I could set stroke: 0 or similar, which “works”. But I cannot use stroke: "Foobar", I believe because that value is interpreted as a data accessor or color name - both of which will fail.

And I believe my use case is not very rare either - when one is sampling multiple sensors at a given frequency and stores the data in a tabular database, one will always run into this problem from what I can gather?

Hah, now that I wrote this down I got one more idea and that seems to work as I would expect it to:

Plot.lineY(powerLogToday, {x: "time", y: "power_ch1", tip: true, stroke: () => "Channel 1"}),

Adding a level of indirection to the stroke via a lambda instead of returning the string as-is makes this work in the way I wanted!

Though I still have to figure out what to do about stacked bar charts in that case then.