13

you for sure know a fast way how I can track down the limits of my figure after having zoomed in? I would like to know the coordinates precisely so I can reproduce the figure with ax.set_xlim and ax.set_ylim. I am using the standard qt4agg backend.

edit: I know I can use the cursor to find out the two positions in the lower and upper corner, but maybe there is formal way to do that?

hitzg
  • 12,133
  • 52
  • 54
varantir
  • 6,624
  • 6
  • 36
  • 57

2 Answers2

35

matplotlib has an event handling API you can use to hook in to actions like the ones you're referring to. The Event Handling page gives an overview of the events API, and there's a (very) brief mention of the x- and y- limits events on the Axes page.

The Axes instance supports callbacks through a callbacks attribute which is a CallbackRegistry instance. The events you can connect to are xlim_changed and ylim_changed and the callback will be called with func(ax) where ax is the Axes instance.

In your scenario, you'd want to register callback functions on the Axes object's xlim_changed and ylim_changed events. These functions will get called whenever the user zooms or shifts the viewport.

Here's a minimum working example:

Python 2

import matplotlib.pyplot as plt

#
# Some toy data
x_seq = [x / 100.0 for x in xrange(1, 100)]
y_seq = [x**2 for x in x_seq]

#
# Scatter plot
fig, ax = plt.subplots(1, 1)
ax.scatter(x_seq, y_seq)

#
# Declare and register callbacks
def on_xlims_change(event_ax):
    print "updated xlims: ", event_ax.get_xlim()

def on_ylims_change(event_ax):
    print "updated ylims: ", event_ax.get_ylim()

ax.callbacks.connect('xlim_changed', on_xlims_change)
ax.callbacks.connect('ylim_changed', on_ylims_change)

#
# Show
plt.show()

Python 3

import matplotlib.pyplot as plt

#
# Some toy data
x_seq = [x / 100.0 for x in range(1, 100)]
y_seq = [x**2 for x in x_seq]

#
# Scatter plot
fig, ax = plt.subplots(1, 1)
ax.scatter(x_seq, y_seq)

#
# Declare and register callbacks
def on_xlims_change(event_ax):
    print("updated xlims: ", event_ax.get_xlim())

def on_ylims_change(event_ax):
    print("updated ylims: ", event_ax.get_ylim())

ax.callbacks.connect('xlim_changed', on_xlims_change)
ax.callbacks.connect('ylim_changed', on_ylims_change)

#
# Show
plt.show()
Adehad
  • 519
  • 6
  • 16
mattjw
  • 466
  • 4
  • 3
2
print ax.get_xlim(), ax.get_ylim()
EL_DON
  • 1,416
  • 1
  • 19
  • 34
  • 1
    This is probably not what OP was asking about; in my experience these functions return the limits given by set_xlim(), but are oblivious to what view the user has manually panned/zoomed afterwards. – dominecf Mar 10 '17 at 14:32
  • 1
    Then why does the accepted answer work? It also uses `.get_xlim`. – EL_DON Apr 27 '17 at 03:22
  • 2
    Yes this answer is correct in the sense that `ax.get_xlim()` will return the current limits of the plot at any point in time, even after zooming. So if one is able to interact with the figure and call such command interactively, e.g. in an IPython session, this works fine. If the plot is produced by a script, you usually do not have this option; in that case the other answer shows how to use the events needed to be able to print the limits. – ImportanceOfBeingErnest Feb 02 '18 at 15:02