Reputation: 135
I have two different matplotlib graphs embedded in tkinter that I am using a button to switch between. The first graph switch cycle plots the graphs as expected however every time thereafter switching between the two graphs causes the first graph to have an unexpected x and y axis set of labels and ticks ranging from 0 to 1. The desired graph one x and y axis labels and ticks are present as expected but in addition an extra 0 to 1 range labels/ticks are overlaid on the expected labels/ticks. The graph two x and y axis labels/ticks behave correctly and do not have the unexpected overlay. The following is a simplified version of my code followed by some pictures of the graphs showing the problem.
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
from tkinter import *
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg,
NavigationToolbar2Tk)
from matplotlib.backend_bases import key_press_handler
import numpy as np
# Separated out config of plot to just do it once
def config_plot():
fig = plt.figure(figsize=(18, 5))
return (fig)
class graphSwitcher:
def __init__(self, master):
self.master = master
self.frame = Frame(self.master)
self.fig = config_plot()
self.graphIndex = 0
self.canvas = FigureCanvasTkAgg(self.fig, self.master)
self.config_window()
self.graph_one(self.fig)
self.frame.pack(expand=YES, fill=BOTH)
def config_window(self):
self.canvas.mpl_connect("key_press_event", self.on_key_press)
toolbar = NavigationToolbar2Tk(self.canvas, self.master)
toolbar.update()
self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH,
expand=1)
self.button = Button(self.master, text="Quit",
command=self._quit)
self.button.pack(side=BOTTOM)
self.button_switch = Button(self.master, text="Switch Graphs",
command=self.switch_graphs)
self.button_switch.pack(side=BOTTOM)
plt.subplots_adjust(bottom=0.2)
# the def creates the first matplotlib graph
def graph_one(self, fig):
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)
self.ax = fig.subplots()
try:
self.ax1.clear() # clear current axes
self.ax2.clear()
except AttributeError:
pass
self.ax.plot(t, s)
self.ax.set(xlabel='time (s)', ylabel='voltage (mV)',
title='Graph One')
self.canvas.draw()
# This def creates the second matplotlib graph that uses subplot
# to place two graphs one on top of the other
def graph_two(self, fig):
x1 = np.linspace(0.0, 5.0)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
self.ax1 = plt.subplot2grid((5, 4), (0, 0), rowspan=4,
colspan=4)
self.ax1.plot(x1, y1, 'o-')
self.ax1.set(title='Graph Two')
means_men = (20, 35, 30, 35, 27)
std_men = (2, 3, 4, 1, 2)
self.ax2 = plt.subplot2grid((5, 4), (4, 0), sharex=self.ax1,
rowspan=1, colspan=4)
self.ax2.bar(std_men, means_men, color='green', width=0.5,
align='center')
self.canvas.draw()
def on_key_press(event):
key_press_handler(event, canvas, toolbar)
def _quit(self):
self.master.quit() # stops mainloop
def switch_graphs(self):
self.graphIndex = (self.graphIndex + 1 ) % 2
if self.graphIndex == 0:
self.graph_one(self.fig)
else:
self.graph_two(self.fig)
def main():
root = Tk()
graphSwitcher(root)
root.mainloop()
if __name__ == '__main__':
main()
The following are pictures of the graphs seen in sequence showing that the first two times the individual graphs are seen (cycle 1) the graphs have the correct axis labels and ticks. But that the second time the first graph is shown there is an extra unexpected set of x and y axis labels and ticks. The las two pictured graphs repeat every cycle (two button pushes)
If anybody has any ideas on how to get rid of the unexpected x and y axis labels/ticks seen on graph one I would appreciate the help.
Upvotes: 2
Views: 831
Reputation: 25362
You're clearing the axes created on the call to graph_two
, but you're not removing them. So when you come to plot the first graph for a second time, the graph_two
axes are still there underneath the axes for graph_one
. You can't see the 2 subplots themselves as they are underneath, but the axes tick labels do show at the edges, which is what you are seeing.
This is more easily seen if you remove the plotting and figure creation in graph_one
you will be able to see that the 2 subplots are cleared but not removed when you press the button.
The solution is therefore simple, use axes.remove
instead. So graph_one
looks like:
def graph_one(self, fig):
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)
self.ax = fig.subplots()
try:
self.ax1.remove() # remove current axes
self.ax2.remove()
except AttributeError:
pass
self.ax.plot(t, s)
self.ax.set(xlabel='time (s)', ylabel='voltage (mV)',
title='Graph One')
self.canvas.draw()
Upvotes: 2