-
-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Description
Problem
For an Axes object axes, axes.viewLim.intervalx defines the view interval for x-axis.
In current version, there are two functions/methods change axes.viewLim.intervalx directly.
One is axes.set_xlim (code), another is axes.xaxis.set_view_interval (code).
Generally we use axes.set_xlim or its wrapper plt.xlim, note the callback mechanism and sharex mechanism are reduced in this method (when emit is True).
However, when we call plt.xticks, axes.set_xticks or axes.xaxis.set_ticks, it uses axes.xaxis.set_view_interval, thus changes axes.viewLim.intervalx directly without callback and sharex. This may cause some unexpected behaviers.
Same situation for y-axis.
Example
from matplotlib import pyplot as plt
a = plt.gca()
a.plot([0,1], [0,1])
b = plt.twinx()
b.plot([0,1], [0,1])
b.set_xticks([1,2,3])
plt.draw()

The two lines in figure should be the same in this figure, as they share x-axis and have the same y-axis limits. It goes wrong becasue that b.set_xticks changes the range of itself but didn't inform its twin axes a.
Solution
Make a new method for axes named _set_view_intervalx or something similar, it aims at change viewLim.intervalx and reduce the callback and sharex.
And let axes.set_xlim and axes.xaxis.set_view_interval call this function to change interval.
We shall make sure this method is the only one who can modify viewLim.intervalx directly.
class _AxesBase(martist.Artist):
...
def _set_view_intervalx(self, left, right, emit=False):
"""
Set the data limits for the xaxis
*emit*: [ *True* | *False* ]
Notify observers of limit change
"""
self.viewLim.intervalx = (left, right)
if emit:
self.callbacks.process('xlim_changed', self)
# Call all of the other x-axes that are shared with this one
for other in self._shared_x_axes.get_siblings(self):
if other is not self:
other.set_xlim(self.viewLim.intervalx,
emit=False, auto=auto)
if (other.figure != self.figure and
other.figure.canvas is not None):
other.figure.canvas.draw_idle()
Sorry if I missed anything obvious or misunderstand the mechanism behind.
I'm new here, any comments are welcome. Feel free to add proper flag and modify the post title, thanks.