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
Y-axis value of a seaborn heatmap is reversed when home icon or H button is pushed #9863
Comments
Can you reproduce in matplotlib only? |
It did not reverse the order when using purely matplotlib with the sample code below import matplotlib.pyplot as plt
import numpy as np
data = np.random.rand(10, 10)
plt.imshow(data)
plt.show() Is it because of seaborn? I did not have any issue before with seaborn 0.8.1 and matplotlib 2.0.2 |
|
Initial plot result of seaborn heatmap (from the sample code) is from 9 ~ 0. I think that is what you mean by inverting matrix order. After pressing H or home icon, the Y axis of the plot changes to 0 ~ 9, this is the issue that I am reporting. The operation of Home/H will reset the plot to initial position after you zoom or pan on the plot. |
import matplotlib
matplotlib.use('Qt5Agg')
import matplotlib.pyplot as plt
import numpy as np
data = np.random.rand(10, 10)
fig, ax = plt.subplots()
ax.imshow(data)
ax.invert_yaxis()
plt.show() This works fine in Master for macosx, Qt5Agg, and TkAgg backends on my machine (zoom, and then home button keeps the axis inverted). So either |
It's working fine also on my machine with matplotlib 2.1.0. The issue occurs when heatmap is generated using seaborn. I guess this is an issue for seaborn ? But why is it working fine with older version of matplotlib 2.0.2 using the same seaborn 0.8.1 version? |
Heatmap uses pcolormesh... |
And inverts the y axis? Replacing imshow with pcolormesh above inverts the axis, but the behaviour still works fine. Maybe the bug was in 2.0.2? import matplotlib
matplotlib.use('Qt5Agg')
import matplotlib.pyplot as plt
import numpy as np
data = np.random.rand(10, 10)
fig, ax = plt.subplots()
ax.pcolormesh(data)
ax.invert_yaxis()
plt.show() |
That's what I am thinking also that maybe the bug is in old version. But for a user perspective if I pushed home button the expected result is that it will take me to where I came from, which for this case is the initial view of my plot. |
I can reproduce your reported behaviour using seaborn. No idea what seaborn does though in heatmap, so its hard to see if we have a bug or seaborn does. I'll leave open, but mark it as needing a downstream fix/investigation. Feel free to reference this Issue when you report to them. |
OK. I figured it out. Here's a minimal example that distills the seaborn import numpy as np
import matplotlib.pyplot as plt
x = np.random.rand(10, 10)
f, ax = plt.subplots()
ax.pcolormesh(x)
ax.figure.draw(ax.figure.canvas.get_renderer())
ax.invert_yaxis()
plt.show() The resetting happens when |
Thanks, that seems to be the problem. I'm not sure why |
That's because the "home" position is defined the first time the canvas is drawn (when else could it be?) and just stores the limits as they are (whether the limits are inverted are part of the position). I actually think this is the correct behavior (there's nothing in matplotlib that directly stores whether an axis is inverted, it's just that you can set xlow>xhigh). So I'm tempted to close this as "not a bug" (or rather, should be fixed on seaborn's side). For seaborn's specific case, I don't think there's any gain to calling draw before calling invert_yaxis (you'll have to redraw the whole thing anyways). |
Ooops, I was just typing that! I agree that seaborn should reconsider issuing a "draw" request, at least before the axis is inverted. OTOH, all the programatic ways to change the xlimits, ylimits, etc do not register in the stack. One could argue that the toolbar stack should only be filled when "show" is called. I couldn't quite follow the trail to see where the "Home" was defined to see what changed. |
Not everyone calls show() (for example, when embedding matplotlib in a GUI where you manage widget visibility yourself), but everyone has to call draw(), so I maintain that it's the correct place to do it. |
seaborn has to force a draw to get the tick labels, but there's probably no compelling reason to delay inverting the axis. |
@anntzer Agreed. But, it'd be nice to know what changed... |
@anntzer Thanks, and, I'm fine w/ that logic. But.... If the first "draw" event gets registered onto the stack, why aren't subsequent ones? i.e. in the above snippet, |
I think it's fine to register later draws as well (the reason it isn't is because I copied the old logic, which similarly also only registered the first view (specifically, at the time a pan/zoom button was pressed for the first time)). |
OK, but thinking about it, isn't that the better behaviour? i.e. only save the initial state when the user starts interacting w/ the figure? What was #6598 trying to fix? |
I played with registering later draws, but of course you are also drawing when zooming and panning, so its hard to just do that.... Anyway, I don't know that this is a huge deal, but I've noted a few people wondering about the behaviour of zoom and pan. I wonder if this change has some connection. @efiring I think was one of them. |
#6598 was handling the case of the limits being changed by the figure options tool (but I guess the other way to do it would be to register the initial position when any UI tool is triggered for the first time). |
That makes sense to me. The point of the navigation buttons is to move among configurations generated via the UI tools, so starting with the plot as first seen when a UI tool is clicked seems like the correct behavior. |
@anntzer were you going to work on this? I could take a stab. I see what you changed, and I see how to get it back to the old behaviour w/o reverting everything you did (I think).. |
Not right now, got for it! |
Well, I won't do it right now ;-), but over the next week or so... |
Bug report
Bug summary
The value of Y-axis in a seaborn heatmap is reversed when home icon or H button is pushed.
Code for reproduction
Actual outcome
Expected outcome
Matplotlib version
print(matplotlib.get_backend())
): TkAggPython3.6 is installed using APT, while matplotlib is installed via pip
The text was updated successfully, but these errors were encountered: