Skip to content
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

Matching axes #1549

Closed
alexcjohnson opened this issue Apr 3, 2017 · 13 comments · Fixed by #3506
Closed

Matching axes #1549

alexcjohnson opened this issue Apr 3, 2017 · 13 comments · Fixed by #3506
Assignees
Labels
feature something new
Milestone

Comments

@alexcjohnson
Copy link
Collaborator

We should allow two (or more) axes to not just share a scaling, but actually force precisely equal range. Use case is plots like this one:
machine-learning-classifier-comparison

This came up in #272 (comment) but was not addressed in #1522 - opening this as a new issue so we don't forget about it.

@tishihar94
Copy link

Hi, any progress with this?

I have two side-by-side scatter plots that are identical, except for the colors of each point (One plot is colored by cluster and the other has a colorscale). It would be great if I could synchronize the zoom/pan so that both the X and Y axis are preserved But I can only get it to synchronize the Y-axis even if I do shared_xaxes=True and shared_yaxes=True.

@alexcjohnson
Copy link
Collaborator Author

We're probably going to need to do this as part of #2372, which is up next, so that the x and y for the same variable can have matched ranges (keeping the diagonal panes diagonal as well). But when we do this it will include matched x and matched y axes as well as x matching y.

@mschilli87
Copy link

mschilli87 commented Nov 14, 2018

@alexcjohnson: #2372 was closed via #2505 but this is still open. So is this possible by now and if so how? I have two scatter plots below each other via subplot and I'd like to have the same axes range on both and zoom synchronously. Am I on the right track?

@alexcjohnson
Copy link
Collaborator Author

@mschilli87 I'm afraid matching axes was not included in the initial SPLOM implementation and has not yet been done on its own, so it's correct for this issue to remain open. In the meantime you may be able to listen to plotly_relayout events and issue new Plotly.relayout calls to keep the axes in sync - but be careful about avoiding infinite loops!

@nicolaskruchten
Copy link
Contributor

A few items that come to mind for ideal 'matched' axes:

  • category order should match
  • histogram auto-binning should align

@etpinard etpinard self-assigned this Jan 18, 2019
@etpinard
Copy link
Contributor

etpinard commented Jan 23, 2019

Quick question: say we have:

Plotly.newPlot(gd, [{
  y: [1, 2, 1]
}, {
  y: [2, 1, 2, 3],
  xaxis: 'x2'
}, {
  y: [0, 1],
  xaxis: 'x3'
}], {
  grid: {rows: 1, columns: 3},
  xaxis2: {matches: 'x'},
  xaxis3: {matches: 'x'}
})

should the axis autorange be computed using data from the three traces or just the first trace?

I think the former would be pretty cool, but I'd like to confirm.

@alexcjohnson
Copy link
Collaborator Author

Absolutely, autorange should take into account all data on any of the matched axes. This is going to be a bit more complicated than just throwing all of that data into the autorange calculation though, because two axes should be able to match range without matching _length - particularly useful for x matching y without forcing the plot to be square.

That begs the question though, how do you specify that you want _length to match too (which seems like it should be the default behavior)? Perhaps you use yaxis: {matches: 'x', scaleratio: 1}, and then whichever would be larger gets its domain reduced in order to match _length? And then by extension, if scaleratio is some other number, that number becomes the ratio of _length values... And if you don't want to match _length at all, you set scaleratio: 0?

One more question: What if you want two axes to match but inverted? I'm thinking of things like x/y match but you want the diagonal to go NW-to-SE... or the population pyramid, with male on one side and female on the other, which you can do with a single axis and positive/negative data, but that requires fudging the data (negating one set) and with two axes you could put the labels in the middle without overlapping the data... Perhaps we could support this with scaleratio: -1?

Anyway we can start with square non-inverted for the first release, but we should plan it so the API will extend to support non-square and inverted at some point.

@etpinard
Copy link
Contributor

etpinard commented Jan 23, 2019

Perhaps you use yaxis: {matches: 'x', scaleratio: 1}

Ok thanks! Interesting, @nicolaskruchten mentioned (in an offline convo) that matching axes of the same letter (i.e. 'x' or 'y') would suffice for the first iteration. I'll see what I can do!

@nicolaskruchten
Copy link
Contributor

should the axis autorange be computed using data from the three traces

yes, definitely.

@nicolaskruchten
Copy link
Contributor

how do you specify that you want _length to match too (which seems like it should be the default behavior)?

If we're just match x-to-x/y-to-y (which is mostly what I'm interested in at the moment) then this is less of a concern because they could just be told to have the same domain fraction.

In terms of x-to-y matching, being able to also say "and make this physically square in pixel-space" would be a nice add-on, but maybe orthogonal to range-matching. I'm thinking of something like a ROC curve which is plotted from 0 to 1 on both axes and in a square plot (which is hard to achieve in plotly.js today without doing the heigh/width/domain calcs outside!) but I don't want matched axes there.

@alexcjohnson
Copy link
Collaborator Author

matching axes of the same letter (i.e. 'x' or 'y') would suffice for the first iteration

if that's a lot easier, OK, it won't cause any API problems to enable it later. But I kind of don't think it'll be that much harder to do x/y matching since we already have that for scale constraints. And it would be really nice to use with splom - it would mean that if you zoom on one off-diagonal subplot, not only would the whole row & column through that subplot zoom but the symmetric row & column would also zoom to match.

@etpinard etpinard added this to the v1.45.0 milestone Jan 24, 2019
@etpinard
Copy link
Contributor

how do you specify that you want _length to match too

Perhaps you use yaxis: {matches: 'x', scaleratio: 1}, and then whichever would be larger gets its domain reduced in order to match _length?

How would this proposal be different than having ax.matches and ax.scaleanchor (under constrain: 'domain') set. For example, wouldn't

yaxis: {
  matches: 'x',
  scaleanchor: 'x',
  scaleratio: 1,
  constrain: 'domain'
}

do exactly as you described with yaxis: {matches: 'x', scaleratio: 1} ?

Moreover, I'm thinking about making:

yaxis: {
  matches: 'x',
  scaleanchor: 'x',
  constrain: 'range'
}

invalid. I'm not sure who should "win-out" between matches and scaleanchor here though.

@alexcjohnson
Copy link
Collaborator Author

How would this proposal be different than having ax.matches and ax.scaleanchor (under constrain: 'domain') set.

Only that I didn’t want to allow scaleanchor at all when you already have matches. I guess it may be clearer that way, as it means “range matches AND scale matches”... just seems weird as the only allowed values of scaleanchor would be ’x’ or nothing.

I’m not sure who should “win out”

Agreed, that would be meaningless.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature something new
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants