Skip to content

Inconsistency between axes.set_xlim and axes.xaxis.set_view_interval #6863

Closed

Description

@syrte

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()

Example
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.


Related post
#5560
#6860

Activity

  1. added this to the milestone on Jul 31, 2016
  2. tacaswell commented on Aug 3, 2016

    @tacaswell
    Member

    👍 seems reasonable to me Can you put that change into a pull request?

  3. changed the title [-]Conflict between `axes.set_xlim` and `axes.xaxis.set_view_interval`[/-] [+]inconsistency between `axes.set_xlim` and `axes.xaxis.set_view_interval`[/+] on Aug 3, 2016
  4. changed the title [-]inconsistency between `axes.set_xlim` and `axes.xaxis.set_view_interval`[/-] [+]Inconsistency between `axes.set_xlim` and `axes.xaxis.set_view_interval`[/+] on Aug 3, 2016
  5. syrte commented on Aug 3, 2016

    @syrte
    Author

    @tacaswell I've submit a PR.
    Add two methods for Axes: _set_viewLim_intervalx and _set_viewLim_intervaly.
    Most behaviors of the two function axes.set_xlim and axes.xaxis.set_view_interval should be same before, except that axes.xaxis.set_view_interval will also update twin axis now.

    Not sure if it is good idea to add new functions, this somehow seems to be just a work around.

  6. modified the milestones: , on Oct 3, 2017
  7. github-actions commented on Mar 27, 2023

    @github-actions

    This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

  8. greglucas commented on Mar 28, 2023

    @greglucas
    Contributor

    I believe this must have been fixed somewhere along the line. I can't reproduce the original issue.

  9. syrte commented on Mar 28, 2023

    @syrte
    Author

    Thanks for the confirmation!

  10. modified the milestones: future releases, v3.4.0 on Jul 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions