-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Aspect ratio key for 2d plots #272
Comments
@jackparmer I'm not entirely clear what the API would be. For gl3d, the API is What'd it be for gl2d ( |
I'm not sure either. @jackparmer are you referring to the aspect ratio of the either graph OR of each If the former, then a If the latter, then ... hmm there's no obvious way to add I'd vote for the former. Since, our Moreover, maybe this issue could be merged with #106 ? |
There are two separate issues here. One is making sure the overall plot keeps a nice shape when the window is resized - like if you have a responsive webpage, it would be cool if the plot could take its width from the container element and its height from this aspect ratio. That should work fine with The second is where the data on a plot has a 2D metric, like if you're showing physical positions in two dimensions, or in momentum space, really anything where x and y have identical units so relative scales and angles are meaningful. The first (
In fact you could say something obviously silly:
I think for the most general case we need to allow both x and y axes to define constraints, otherwise there would be no way to create a legitimate fully-constrained 2x2 layout, or even three subplots (central, top, and right, for example). We could just say it's an error to define a circular constraint reference, that should avoid this problem.
|
I agree there are two different types of ratios, one which ignores the data range (in ggplot2, this is By the way, the main idea behind plotly/plotly.R#509 is to essentially ensure |
@cpsievert right, this has to be done in the js library itself for the aspect ratio to survive nearly all our interactivity. I suppose you're right that having different aspect ratios on different subplots is an unusual case, but having some subplots that want a fixed ratio and others that don't seems like a fairly common case, at which point we've nearly arrived at each one supporting its own aspect ratio anyway. |
True, I suppose it would be nice to have that flexibility if it's doable (just FYI, I won't need this for our ggplot2 converter). In that case, from a user perspective, it might be nice for subplot specific ratios to inherit from a global ratio. |
Thanks everyone for the discussions. I feel they help make the problem more clear in my mind. The issue with the layout aspect ratio, as @etpinard said, could be addressed by letting On the other hand, from @alexcjohnson 's comment, I now understand that setting the subplot aspect ratio through Currently, Assuming the layout aspect ratio is specified using percentage units in Instead of defining another table for the aspect mode (
What do you think? Would something like this work? |
To be a little more clear, I would be estatic with library(ggplot2)
ggplot(mtcars) +
geom_point(aes(wt, mpg)) +
facet_wrap(~vs) +
coord_equal() versus ggplot(mtcars) +
geom_point(aes(wt, mpg)) +
facet_wrap(~vs, scales = "free_x") +
coord_equal() So, in other words, when |
Some various use-cases of aspect ratios:
|
To put it bluntly, important parts of the R community won't take us seriously until we have 2D aspect ratios, and our In attempt to generalize the use cases already mentioned, aspect ratios are important whenever you have 2 axes that have some sort of meaningful connection in what they measure (not necessarily physical space). So, they are not only important for data visualization (e.g., maps), but also for statistical graphics, where we often visualize (via biplots, tours, etc.) 2D projections of a high-dimensional data (e.g., MDS, PCA, etc). In those projections, there is almost always a meaningful connection between the axes (e.g., each axis might represent the amount of variation explained). |
I agree with, as e.g. @n-riesco and @alexcjohnson said on the top, that these are separate concerns:
This is a currently working, manual way of achieving uniform axis scaling (put together on a client request). Of course the problem is that things have to be calculated to make it just right. I think that to achieve the 2nd goal - uniform, or specified axis scaling - it should be possible to express relationship among axes, or generalizing it to our multi-axis support for Btw. if there's a more accepted term than uniform axis scaling, we could use that. In my mind, aspect ratio is a relationship between the width and height of a rectangle in screen space while uniform axis scaling, or relative axis scaling is a relationship among axes about their domain extent (length) to corresponding screen projection length ratio. For example, this codepen example has a uniform (1:1) axis scale ratio but a 3:5 aspect ratio. Going through the aspect ratio is convoluted because it assumes knowledge of the projected axis domain extent. |
Yes, this is a tricky one - on the other hand we would like it to be flexible and clear which axes you're linking with any given attribute. I think what I'd like to do is describe these linkages within the axis objects and then check for incompatible constraints at the end. A closely related feature, that I'm not going to build right now but I'd like to think about so it can fit into this framework, is forcing two axes to be identical - not just the same scaling, but in fact exactly the same range. I'm thinking of plots like this one: For an API, I'm thinking:
I'm also thinking while technically possible, it might be best to forbid a single axis having both xaxis: {},
yaxis: {scalewith: 'x', scaleratio: 10},
xaxis2: {match: 'x'},
yaxis2: {match: 'y'} Then all we'd need to do to avoid incompatible constraints is disallow loops - probably just refuse to set Thoughts about this API? |
Identical axes are great for SPLOM, small multiple plots, even parcoords. Speaking of which, a side note is that the convention there isn't currently a Re Very loosely related thing: on past work, sometimes I needed to model things such as projections and axes separately. For example, there would be a small multiples grid, but there'd also be a hero chart - such as a highlight of one of the ones in the grid - with essentially the same axes but projecting it over a larger screen area. Another example, minimap - a miniature version of the hero chart, which shows the entire data domains (and a rectangle highlight for the hero's current domain extent). Some but not all axis data are shared. Maybe it's worth thinking about internally modeling scales / projections / axes as shareable 1st class entities, otherwise a lot of charts in a trellised or faceted arrangement will repeat the same expensive axis generation calculation. It might not be an issue now, but it would probably be for trellises with a lot of panels or points, or some dashboard with live updates on streaming data. As these things are probably heading our way, maybe it's good to consider an internal projection abstraction to let shared calculations happen only once. |
I was imagining that it would be chainable: xaxis: {},
yaxis: {scalewith: 'x'},
// multiple axes all scaled with the first one
yaxis2: {scalewith: 'x'},
// another one, that implicitly links the scale back to x
xaxis2: {scalewith: 'y'},
// this would be equivalent to scalewith 'x' but if you
// use scaleratio these will multiply together differently
// depending on where you hook yaxis3 into the chain
yaxis3: {scalewith: 'x2'}
Good point. I don't think we want to change the API based on this, but down the road this would be a good way to boost our capabilities for these large, complex plots. |
I guess |
I, of course, don't have as much expertise on the topic as @monfera or @cpsievert so I have a hard time picturing if @alexcjohnson's proposal scales well enough to cover all the interesting cases. It definitely takes care of the easy cases well and is pretty friction-less. I'd say adding another first-class object as @monfera proposed sounds like an overkill for this feature. About @alexcjohnson 's
👍 about logging something. I would be nice to make Maybe we should add a Moreover, to me scalemode: 'independent' (the default of course) || 'ratio' || 'match',
value: /* numeric value for 'ratio', string id for 'match' */,
// or
scaleratio: /* only coerced for 'ratio' */
scalematch: /* only coerced for 'match' */ would be best? |
To state/clarify the obvious, is this only a concern of the cartesian plot type? Would 2d gl plots need/want this too and need to hoist it up out of the cartesian plot code? |
We should definitely make this work with gl2d. When we get to |
Chatted about this with @etpinard on slack - |
+1. Related to plotly/plotly.py#70 as well? |
@tachim Yup. This will solve that issue for the Python lib 👍 |
So, is it actually possible to link multiple axes while maintaining their aspect ratios? When I try the following as discussed above:
it throws a warning: |
Similar to:
https://plot.ly/python/reference/#layout-scene-aspectratio
For 3d plots
The text was updated successfully, but these errors were encountered: