observablehq / plot

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

Automatic margins based on tick label length #383

Open ericemc3 opened 3 years ago

ericemc3 commented 3 years ago

A Plot could be internally composed in a harmonious and adaptive way, taking into account the actual bounding box of tick labels and axis titles for example, rather than having you to manually specify margins.

Here I need to enter a guestimate marginLeft:110 to accomodate labels width:

image

A manual specification of margins is not robust: if unit or data change, or the font family/size used for the axes, overlaps may occur, or unsightly gaps may appear.

Note: ggplot2 and vega-lite automatically handle margins/padding inferred from axis (and legends) bounding boxes.

Plus, an option comparable to labelOverlap in vega-lite would allow the density of tick labels on a numerical or temporal axis to be managed harmoniously, avoiding any overlap.

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!

Fil commented 3 years ago

Adapting to labels' lengths would also make the chart behave unpredictably. There should be a better method than guesstimating though.

ericemc3 commented 3 years ago

Well i don't see ggplot2 or vega-lite behave unpredictably to that regard, and i have already handle this with D3 in the past (SVG or canvas provides methods for measuring BB and texts length after painting). Could you please elaborate on what you fear might become unpredictable?

mbostock commented 3 years ago

We chose not to do this both to keep things simple and because we want the margins to be consistent across plots for vertical alignment. However, I would like to truncate long labels with ellipsis rather than letting them get cropped by the edge of the chart #394, and I would also like to explore smarter defaults for large numbers (e.g., automatically converting to thousands, millions, or billions) #395.

That said, I could see opting-in to this somehow if the other approaches are insufficient.

ericemc3 commented 3 years ago

I agree that in any case a maximum label width should prevail and ellipsis are a convenient and elegant truncation option.

enjalot commented 2 years ago

What about a compromise where the default marginLeft for ordinal scales is a bit wider than 60px, as that's often much too short for categorical labels.

Every time I make a Plot with ordinal Y axis I change the margin, because reading the labels is higher priority than the consistency in vertical alignment, especially while I'm in the process of exploring the data and trying to generate many Plots rapidly.

Fil commented 2 years ago

@enjalot would we restrict this to ordinal scales? I could see the defaults being different for numbers and for strings… In practice I often have to marginLeft in both cases, since the defaults for numbers are also a bit too small for 5 or 6 digits, but in that case maybe we just need a few pixels more.

enjalot commented 2 years ago

@fil I too often change the defaults for numbers. but not quite as often and not by as much as for strings.

enjalot commented 2 years ago

something I just ran into: the small margin cut off numbers which at first glance didn't look wrong at all. took me a while to notice the problem because the code was so simple i was sure i didn't do anything "wrong"

Screen Shot 2021-12-21 at 12 54 28 PM
Fil commented 2 years ago

This issue was made a bit worse by the new tabular style on numbers.

kospl commented 2 years ago

Any updates on this? : image

mbostock commented 2 years ago

Please don’t pester for updates. If there are updates, you’ll see them here.

kospl commented 2 years ago

Of course, just had to post something here to not create another issue, that will be closed as obviously there is better use case then mine, anyway thanks.