You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I raised this on SO see link here. The comments there provide clarity on this issue.
Started seeing this after I upgraded to 1.5 - but not sure if this is an issue just for 1.5.
The following code shows that, with the default settings, the secondary (RHS) y axis' max tick does not equal to its ylim top.
It doesn't feel like a bug, but it could be a behaviour that is nice to have, for example, when I need to match the grid lines for both axes manually by making sure that the chart actually shows the same number of ticks on both axes. At the moment RHS axis has 8 ticks but the chart only shows 7 of them by default. You can fix this with set_ybound(upper=...) but it's just a little inconvenient.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
x = [x + 0.5 for x in range(10)]
z = [(y+0.0)/10-0.004 for y in range(10)]
df1 = pd.DataFrame({'x': x})
df2 = pd.DataFrame({'z': z})
fig, ax1 = plt.subplots()
# df1.plot(ax=ax1)
ax1.plot(df1)
ax2= ax.twinx()
# df2.plot(ax=ax2, c='r')
ax2.plot(df2, c='r')
# uncommet this line below to set bounds explicitly which fixes this.
# ax2.set_ybound(upper=1.2)
print('ax1 ticks', ax.get_yticks())
print('ax2 ticks', ax2.get_yticks())
print('ax1 ybound', ax.get_ybound())
print('ax2 ybound', ax2.get_ybound()) # this shows the issue
print('ax2 ylim', ax2.get_ylim()) # this shows the issue
Output prints, Note: ax2's ylim & ybound max value are both 1 rather than 1.2, which is the max of its ticks:
Updated code above to use ax.plot instead of DataFrame.plot.
Managed to upload the chart. Note that the RHS axis (variable ax2 in code) upper bound is at 1.0, but get_ticks() shows array([-0.2, 0. , 0.2, 0.4, 0.6, 0.8, 1. , 1.2]), question is why the upper bound isn't 1.2 by default, as suggested by the maximum tick value?
This can be inconvenient sometimes. For example, one way to align the grid lines from both axes is to make sure both axes have the same number of ticks. (Welcome other suggestions!) The no. of ticks for RHS in the chart displayed do not match len(ax2.get_yticks()), which makes it a little inconvenient when determine what should be the common number of ticks for both axes.
get_yticks falls back to calling ax2.yaxis.major.locator() which asks the major locator instance where to put ticks. The way this is used internally in the library, this call is allowed to return extra locations (that may not be visible on the graph).
The way that mpl is implemented underneath the tick locators, the tick formatters, and the axis limits are implemented independently (and that is definitely a feature).
Thanks for the explanation. What's the benefit of allowing ax2.yaxis.major.locator() to return extra locations that may not be visible on the graph?
Also when you say that it is a feature to implement tick locator/formatter/axis limits independently, what are the benefits to do so? Just trying to understand the essence of its design.
The primary benefit, IIRC, is to better handle situations involving
floating point (im-)precision (i.e., by having extra ticks available in
case one of them may actually be desirable).
Thanks for the explanation. When you say that it is a feature to implement
tick locator/formatter/axis limits independently, what are the benefits to
do so? Just trying to understand the essence of its design. Appreciate it!
—
Reply to this email directly or view it on GitHub #5560 (comment)
.
Activity
tacaswell commentedon Nov 25, 2015
I do not really understand either this issue or the SO question.
Can you provide an example which does not go through pandas plotting?
esvhd commentedon Nov 25, 2015
Updated code above to use
ax.plotinstead ofDataFrame.plot.Managed to upload the chart. Note that the RHS axis (variable
ax2in code) upper bound is at 1.0, butget_ticks()showsarray([-0.2, 0. , 0.2, 0.4, 0.6, 0.8, 1. , 1.2]), question is why the upper bound isn't 1.2 by default, as suggested by the maximum tick value?This can be inconvenient sometimes. For example, one way to align the grid lines from both axes is to make sure both axes have the same number of ticks. (Welcome other suggestions!) The no. of ticks for RHS in the chart displayed do not match
len(ax2.get_yticks()), which makes it a little inconvenient when determine what should be the common number of ticks for both axes.Hope this helps to clarify. Thanks.
tacaswell commentedon Nov 25, 2015
So the minimal example is:
get_yticksfalls back to callingax2.yaxis.major.locator()which asks the major locator instance where to put ticks. The way this is used internally in the library, this call is allowed to return extra locations (that may not be visible on the graph).The way that mpl is implemented underneath the tick locators, the tick formatters, and the axis limits are implemented independently (and that is definitely a feature).
esvhd commentedon Nov 25, 2015
Thanks for the explanation. What's the benefit of allowing
ax2.yaxis.major.locator()to return extra locations that may not be visible on the graph?Also when you say that it is a feature to implement tick locator/formatter/axis limits independently, what are the benefits to do so? Just trying to understand the essence of its design.
Appreciate it!
WeatherGod commentedon Nov 30, 2015
The primary benefit, IIRC, is to better handle situations involving
floating point (im-)precision (i.e., by having extra ticks available in
case one of them may actually be desirable).
On Wed, Nov 25, 2015 at 5:47 PM, esvhd notifications@github.com wrote:
efiring commentedon Jan 26, 2018
If I understand the comments correctly, this can be closed now. If I have misunderstood, please reopen it.