It’s not intended to be used that way, primarily; it’s intended to be used with one cell per chart, so that you can use the Observable UI to reorder the time series or comment on them separately. But we could include an example of that as an advanced topic.
Thank you for continuing your wonderful work!
Not to be critical, but I can't help but wonder about the usability of the TimeChart representation.
Even after using the tooltip and reading the other notebooks that describe Horizon Charts, I struggle to understand how to interpret the combination of color and vertical offset. Perhaps adding a color swatch legend with labeled value ranges would help?
Also, is TimeChart recommended for any time-series or just data with smooth/continuously varying values like those that can be approximated with sine -- I wonder how easy it would be to interpret if the values did not vary smoothly, such as random values.
Thanks!
I’ve been using horizon charts for years (e.g. [1]) so I would say try it for a while and see if you like it? It’s definitely my go-to for looking at time series. If you have strictly random (or highly noisy) values you’re not likely to see anything interesting by visualizing anyway, so it’s hard to answer your question directly.
Also, if you want to ease it to horizon charts, you could start by setting the bands: 1 option and you’ll get a basic area chart.
[1] https://square.github.io/cubism/
Thanks for your response and the link. Sorry for not being clearer, but when I ask about usability I am attempting to speak for the person who may not be an expert in interpreting visualizations.
Our time-series customers are used to oscilloscope traces and I'm just wondering if they can benefit from horizon charts.
Since most charts that use color to show quantities include a legend to aid interpretation, please consider this as a suggestion for possibly improving TimeChart to make it more usable/useful for the non-expert.
Regarding the question about smoothly varying values -- yes strictly random is a bad example -- a better example would be a dataset consisting of smoothly varying values (like you have) but with some far/extreme outliers mixed in. I'm not seeing that sort of data on the Cubism page either. . .
Thanks again!
I recommend reading the paper for more about the rationale for the design of horizon charts:
http://vis.berkeley.edu/papers/horizon/
In my experience, yes, horizon charts do take a bit of introduction, but that readers quickly become familiar with the form and find it intuitive. I feel horizon charts are best for displays such as time-series dashboards that you look at frequently or repeatedly; if it’s a form that you see often, the cost of learning the form is amortized over time. Horizon charts are especially good because you can see both small variations (within a band = position) and large variations (across bands = color). That’s what is meant by a “compact” representation versus the equivalent area chart.
As a practical matter, there isn’t really room for a y-axis with this sort of display, and it would introduce a lot of noise if you repeated it for each chart. It might be reasonable to include a threshold color legend (see https://observablehq.com/@d3/color-legend for one implementation) but since the display is interactive rather than static you can also simply mouseover the chart to read the exact values.
We once used horizon charts on the front page of the New York Times in print. I can’t find a good link for it, and admittedly it was only a single-band horizon chart with diverging values (for the forecast probabilities of Republican and Democrat Senate candidates), but here’s a Pinterest screenshot someone captured:
https://user-images.githubusercontent.com/230541/115891515-04611980-a40b-11eb-8af9-20afa344f93f.png
The charts assume a zero baseline, but you could pass TimeChart values that are relative to the baseline if you prefer (and you could use a custom format function to undo the effect of the baseline). For example, data.map(({date, value}) => ({date, value: value - 1})) and then {format: value => value + 1}.