-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
searborn adaptation need for Matptotlib-2.2.0rc1 #10585
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
Comments
so it comes from this change: how should we rewrite an old code like :
is it ?:
|
attn @efiring I think was was intentional to account for interactions between twin, shared axes, and fixed aspect ratio. |
ok, I patched seaborn for my need. seaborn maintainer ask if this internal breakage could be avoided: |
Can you distill to a non-seaborn example? I’m still not sure what seaborn is trying to do that breaks, but I haven’t read the source. |
Similar examples would come from holoviews (replace 'bokeh' per 'matplotlib'): |
more similar would be with hv.Histogram, yet more verbose than compact seaborn
|
I meant can you trigger the error using matplotlib only? |
hum, it's not an internal error of Matplotlib-2.2.0rc1, if that is your question. |
So I'm confused; is this a matplotlib problem (i.e. something that worked pre #10033)? If so, then it must be triggerable with just matplotlib calls. |
seaborn was using an "internal API", functions starting per the undescore characters:
|
The change in |
ok. I agree it was probably a functional bug of seaborn. |
seaborn shouldn't have been using a private method here, but if the issue is just redundancy, is there any reason matplotlib needs to raise on getting |
Here's a self-contained example of what works on 2.1.1 and I gather fails on 2.2: f, (ax0, ax1) = plt.subplots(1, 2, sharey=True)
ax2 = ax1._make_twin_axes(sharex=ax1, sharey=ax0) |
BTW the reason seaborn was using the private method is that I don't believe it is possible through the public API to create a shared twinned axes (at least, |
I don't yet understand what you are trying to do in that example. It looks like ax1 and ax2, the twins with their shared x-axis, are being forced to have the same y-axis as well, via the sharing with ax0. In that case, what is the need for having both ax1 and ax2? Their x axes are identical, and their y axes are identical, so why do you need two Axes? Adding the check to |
The actual use case is a bit more complicated. The goal is to make a home for the for the histograms on the diagonal axes of a seaborn
As I see it, the error here is a false positive because ax2 really does share one axis with its twin. It's raised because Granted, this is a private API, so you can feel free to change it at will, but if an easy fix could avoid completely breaking a popular seaborn function, that would be rad. |
If this can't be achieved w/ the public API, then we should develop a public API to do it, and have tests etc. @mwaskom can you make a 2x2 (or 3x3) toy example that shows the full use case? It seems like a useful feature. |
When you create an axes, you can set its For now, I think you can do: ax._shared_x_axes.join(ax, masterxaxes)
ax._shared_y_axes.join(ax, masteryaxes) I think that is closer to what is wanted, rather than twinning the axes, but maybe I'm misunderstanding.. |
I agree. But in the meantime, this change will break one of the most basic seaborn examples, so I'd really also like to advocate for a minor change to the work in #10033 that won't, as far as I understand, undermine any of its actual goals or otherwise allow incorrect specifications.
This is basically what happens in seaborn: f, axes = plt.subplots(2, 2, figsize=(6, 6), sharex="col", sharey="row")
diag_axes = []
for ax in np.diag(axes):
if diag_axes:
diag_ax = ax._make_twin_axes(sharex=ax,
sharey=diag_axes[0])
else:
diag_ax = ax._make_twin_axes(sharex=ax)
diag_ax.set_axis_off()
diag_axes.append(diag_ax) |
@jklymak Really the simplest thing would be an Maybe I'm completely missing something about the goal of #10033 though... |
Please let me know if, at least, the usecase is clear, because I really think it's quite straightforward and perhaps being overthought. |
Thanks very much for the clear example. OTOH, I'm not personally in favour of accomodating this. As @efiring said, seaborn over-specified the We could put a janky test in On a larger scale, it seems twinning is the wrong thing to do altogether. If I understand correctly, you don't want a twin, you really want the diagonal axes to have different sharex and sharey than Just my opinion. I'm sure a PR to put the check you want would be evenhandedly evaluated. |
BTW, I'll re-open just in way of getting on more people's radars... I'll also milestone, because if we are going to change something, it should happen before 2.2, but feel free to un-milestone if we don't think this is going anywhere. |
The reason is mainly because that's exactly what |
Maybe, maybe not. Given that I'm copying what matplotlib does, I suspect there may be a good reason for it. And in any case, if 2.2 lands with this it will break all existing versions of seaborn with no way to work around the problem. And the "do a scatterplot matrix" is often the first one-liner people use to introduce seaborn, so that's going to mean problems for a lot of people.
seaborn actually does require twin axes because the upper-left hand axes has to have the correct ticks for the other axes in that row. And also it's possible to use the |
Speaking as a matplotlib dev with no attachment to the APIs in question, I'm sensitive to the idea that we not break one of the more prominent downstream libraries. So I'm ok with getting in a change to avoid this breakage before we cut 2.2. I'm also pretty damned irritated that we have to work around this prominent library using an internal API; especially since it seems that this downstream library has made no effort whatsoever in getting a public version of this API. (Please correct me if I'm wrong on this.) So I'm also tempted to say that unless a seaborn dev is willing to put some skin in the game and propose a PR to get a public API that serves their purpose, we don't do a thing. THIS is literally the reason that as a developer of another project, YOU DON'T USE SOMEONE ELSE'S INTERNAL APIS. |
OK, fair enough - tracing through all the twin code is difficult. I did reopen and remilestone so this will at least get discussion before 2.2 drops.
EDIT: Ooops, crossing comments.... |
Thanks @dopplershift for the constructive contributions. |
My proposal is literally to change if 'sharex' in kwargs and 'sharey' in kwargs:
raise ValueError("Twinned Axes may share only one axis.") to if 'sharex' in kwargs and 'sharey' in kwargs:
if kwargs["sharex"] is not self and kwargs["sharey"] is not self:
raise ValueError("Twinned Axes may share only one axis.") |
We can also have a conversation about a public API for twinned, shared axes (which I've proposed above), but that shouldn't be a blocker for 2.2. And, as noted, fixing this error check would be a precondition for making that possible. |
@mwaskom is it not possible write (or just copy the old code in |
No. |
Why not? |
That doesn't solve the problem of all the existing installs being broken. |
Closed #10622 |
Bug report
Bug summary
My historic Seaborn example doesn't seem to work anymore with Matplotlib-2.2.0rc1. is it a volontary change ?
Actual outcome
Matplotlib version
print(matplotlib.get_backend())
):module://ipykernel.pylab.backend_inlineThe text was updated successfully, but these errors were encountered: