Home > Enterprise >  Keep zoom and ability to zoom out to current data extent in matplotlib.pyplot
Keep zoom and ability to zoom out to current data extent in matplotlib.pyplot

Time:12-15

I want to be able to replot data in an interactive matplotlib figure, keeping the zoom that is present. The Internet says to use set_data. This works.

What doesn't work is then being able to click the home button to see the entire extent of the new data I've just replotted.

How can I force the home button to show me all of the data currently plotted? This all happens inside a tKinter window.

Some example code:

import matplotlib.pyplot as plt

x1 = [1, 2, 3, 4, 5, 6]
y1 = [3, 4, 5, 6, 7, 8]

x2 = [2, 3, 4, 5, 6, 7]
y2 = [8, 7, 6, 5, 4, 3]

# plot data
line, = plt.plot(x1, y1, marker="o")

# zoom in - this actually happens by user interaction with the zoom tool
plt.xlim(2.5, 5.5)
plt.ylim(3, 6)

# replace data, maintaining zoom. This actually happens by the user choosing new data to plot
line.set_data(x2, y2)

plt.show()
# now, I want to unzoom to show all of x2,y2 by pressing the "home" button
pass

CodePudding user response:

The "Home" button takes you back to the zoom that has been registered as default. You should set it programmatically.

I do not know a direct interface for setting this default, but you can register the current status of the Canvas as the default, using ToolBar's push_current method.

In your case, you should make this in the place where you change the data. Instead of simply changing the data

line.set_data(x2, y2)

you should do some bookkeeping:

fig = plt.gcf() # I assume the OP already has this data
ax = fig.gca() # I assume the OP already has this data

# save the current zoom for restoring later
old_x_lim = ax.get_xlim()
old_y_lim = ax.get_ylim()

# let matplotlib calculate the optimal zoom for the new data
ax.relim()
ax.autoscale()

# Now the tricky part... I did not find much documentation on this
toolbar = fig.canvas.manager.toolbar
toolbar.update() # Clear the axes stack
toolbar.push_current()  # save the current status as home
ax.set_xlim(old_x_lim)  # and restore zoom
ax.set_ylim(old_y_lim)

I hope this works in you setup. Otherwise you need to poke into matplotlib's internals.

  • Related