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.