I have an application where I have one figure with nine line plot sub-plots (3x3) and I want to let the user select one of the charts and have a small wx Python application open up to allow editing and zooming on the specified sub-plot.
Is it possible to grab all the information from the selected sub-plot, i.e. axis labels, axis formatting, lines, tick sizes, tick labels, etc and plot it quickly on the canvas of the wx application?
My current solution is too long and bulky, as I just re-do the plot that the user selects. I was thinking something like this, but it doesn't work quite right.
#ax is a dictionary containing each instance of the axis sub-plot
selected_ax = ax[6]
wx_fig = plt.figure(**kwargs)
ax = wx_fig.add_subplots(111)
ax = selected_ax
plt.show()
Is there a way to save the properties from getp(ax) to a variable and use selected properties of that variable with setp(ax) to construct a new chart? I feel this data must be accessible somehow, given how quickly it prints when you call getp(ax), but I can't even get the following code to work on an axis with two y-axes:
label = ax1.yaxis.get_label()
ax2.yaxis.set_label(label)
I have a feeling this isn't possible, but I thought I would ask anyways.
Unfortunately, cloning an axis or sharing artists between multiple axes is difficult in matplotlib. (Not completely impossible, but re-doing the plot will be simpler.)
However, what about something like the following?
When you left-click on a subplot, it will occupy the entire figure, and when you right-click, you'll "zoom out" to show the rest of the subplots...
import matplotlib.pyplot as plt
def main():
fig, axes = plt.subplots(nrows=2, ncols=2)
for ax, color in zip(axes.flat, ['r', 'g', 'b', 'c']):
ax.plot(range(10), color=color)
fig.canvas.mpl_connect('button_press_event', on_click)
plt.show()
def on_click(event):
"""Enlarge or restore the selected axis."""
ax = event.inaxes
if ax is None:
# Occurs when a region not in an axis is clicked...
return
if event.button == 1:
# On left click, zoom the selected axes
ax._orig_position = ax.get_position()
ax.set_position([0.1, 0.1, 0.85, 0.85])
for axis in event.canvas.figure.axes:
# Hide all the other axes...
if axis is not ax:
axis.set_visible(False)
elif event.button == 3:
# On right click, restore the axes
try:
ax.set_position(ax._orig_position)
for axis in event.canvas.figure.axes:
axis.set_visible(True)
except AttributeError:
# If we haven't zoomed, ignore...
pass
else:
# No need to re-draw the canvas if it's not a left or right click
return
event.canvas.draw()
main()
Here's a working example that uses a class to store the subplot (axis) selected by the user (the zoomed axis). From the stored axis, you can get all of the information you need. This demo, for example, shows how to zoom and restore the subplot (axis). You can then write other methods in the class that have access to the selected axis to fit your needs.
import matplotlib.pyplot as plt
class Demo(object):
""" Demo class for interacting with matplotlib subplots """
def __init__(self):
""" Constructor for Demo """
self.zoomed_axis = None
self.orig_axis_pos = None
def on_click(self, event):
""" Zoom or restore the selected subplot (axis) """
# Note: event_axis is the event in the *un-zoomed* figure
event_axis = event.inaxes
if event_axis is None: # Clicked outside of any subplot
return
if event.button == 1: # Left mouse click in a subplot
if not self.zoomed_axis:
self.zoomed_axis = event_axis
self.orig_axis_pos = event_axis.get_position()
event_axis.set_position([0.1, 0.1, 0.85, 0.85])
# Hide all other axes
for axis in event.canvas.figure.axes:
if axis is not event_axis:
axis.set_visible(False)
else:
self.zoomed_axis.set_position(self.orig_axis_pos)
# Restore all axes
for axis in event.canvas.figure.axes:
axis.set_visible(True)
self.zoomed_axis = None
self.orig_axis_pos = None
else: # any other event in a subplot
return
event.canvas.draw()
def run(self):
""" Run the demo """
fig, axes = plt.subplots(nrows=2, ncols=2)
for axis, color in zip(axes.flat, ['r', 'g', 'b', 'c']):
axis.plot(range(10), color=color)
fig.canvas.mpl_connect('button_press_event', self.on_click)
plt.show()
def main():
""" Main driver """
demo = Demo()
demo.run()
if __name__ == "__main__":
main()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With