python – 如何使用按钮在matplotlib中的两个不同图形之间切换
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – 如何使用按钮在matplotlib中的两个不同图形之间切换,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含10479字,纯文字阅读大概需要15分钟。
内容图文
![python – 如何使用按钮在matplotlib中的两个不同图形之间切换](/upload/InfoBanner/zyjiaocheng/704/24bd25b3dec74ecf8bd584e02f3882fd.jpg)
我有两个不同的matplotlib图表,我想在按下按钮之间切换.当按下按钮时,我的代码将在第一个图形下面添加第二个图形但我希望它替换第一个图形.这是一个有点类似的stackoverflow问题(How to update a matplotlib embedded into tkinter?),但我似乎无法将此应用于我的情况.
我编写的图形,graph_one和graph_two,是我从matplotlib文档中提取的两个简单图形.在我的实际使用中,我有两个更复杂的图形非常不同,一个是单个图,另一个是另外的子图.因为我希望在它们之间来回切换的图形是如此不同,所以对我来说重要的是解决方案能够将图形输入作为单独的定义来处理.还应该注意的是,我的图形嵌入在tkinter小部件中,重要的是该解决方案也考虑了这种嵌入.
这是我的代码:
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
import numpy as np
from tkinter import *
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
def graph_one():
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)
fig, ax = plt.subplots()
ax.plot(t, s)
ax.set(xlabel='time (s)', ylabel='voltage (mV)',
title='Graph One')
#plt.show()
return fig
def graph_two():
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.cos(2 * np.pi * t)
fig, ax = plt.subplots()
ax.plot(t, s)
ax.set(xlabel='time (s)', ylabel='voltage (mV)',
title='Graph Two')
#plt.show()
return fig
class matplotlibSwitchGraphs:
def __init__(self, master):
self.master = master
self.frame = Frame(self.master)
self.embed_graph_one()
self.frame.pack(expand=YES, fill=BOTH)
def embed_graph_one(self):
fig = graph_one()
canvas = FigureCanvasTkAgg(fig, self.master)
canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
canvas.draw()
canvas.mpl_connect("key_press_event", self.on_key_press)
toolbar = NavigationToolbar2Tk(canvas, self.master)
toolbar.update()
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)
def embed_graph_two(self):
fig = graph_two()
canvas = FigureCanvasTkAgg(fig, self.master)
canvas.draw()
canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
canvas.mpl_connect("key_press_event", self.on_key_press)
toolbar = NavigationToolbar2Tk(canvas, self.master)
toolbar.update()
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)
def on_key_press(event):
print("you pressed {}".format(event.key))
key_press_handler(event, canvas, toolbar)
def _quit(self):
self.master.quit() # stops mainloop
def switch_graphs(self):
self.embed_graph_two()
def main():
root = Tk()
matplotlibSwitchGraphs(root)
root.mainloop()
if __name__ == '__main__':
main()
好像我应该可以使用像这样的命令
ax.clear()
在switch_graphs def中清除第一张图但不起作用.任何帮助,将不胜感激.
我发布了更新的代码,以显示我已经取得的一些小进展,以及更好地代表我希望切换的两个图形的不同性质.这两个图表仍然是直接从matplotlib文档中获取的简单图形,但它们更好地表示我的一个图形是单个图形,而第二个图形具有直接位于彼此之上的两个图形.
在我的实际情况中,我试图使用一个按钮,能够在带有体积覆盖的烛台图表和没有体积覆盖的烛台图表之间切换.发布显示烛台图表的所有代码将产生很长的代码,所以我通过使用这些更简单的图表简化了它.为简单起见,我还删除了matplotlib的导航工具栏.这是我修改后的代码:
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
import numpy as np
from tkinter import *
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
class matplotlibSwitchGraphs:
def __init__(self, master):
self.master = master
self.frame = Frame(self.master)
self.embed_graph_one()
self.frame.pack(expand=YES, fill=BOTH)
# the def creates the first matplotlib graph
def graph_one(self):
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)
fig, ax = plt.subplots()
ax.plot(t, s)
ax.set(xlabel='time (s)', ylabel='voltage (mV)',
title='Graph One')
# plt.show()
return fig, ax
# This def creates the second matplotlib graph that uses subplot
# to place two graphs one on top of the other
def graph_four(self):
x1 = np.linspace(0.0, 5.0)
y1 = np.cos(2 * np.pi * x1) * np.exp(-x1)
fig = plt.figure()
ax = plt.subplot2grid((5, 4), (0, 0), rowspan=4, colspan=4)
ax.plot(x1, y1, 'o-')
means_men = (20, 35, 30, 35, 27)
std_men = (2, 3, 4, 1, 2)
ax2 = plt.subplot2grid((5, 4), (4, 0), sharex=ax, rowspan=1,
colspan=4)
ax2.bar(std_men, means_men, color='green', width=0.5,
align='center')
return fig, ax
# this def takes graph one and embeds it in a tkinter widget
def embed_graph_one(self):
fig, ax = self.graph_one()
canvas = FigureCanvasTkAgg(fig, self.master)
canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
canvas.draw()
canvas.mpl_connect("key_press_event", self.on_key_press)
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=lambda: self.switch_graphs(canvas, fig, ax))
self.button_switch.pack(side=BOTTOM)
# This def takes the second graph and embeds it in a tkinter
# widget
def embed_graph_two(self):
fig, ax = self.graph_two()
canvas = FigureCanvasTkAgg(fig, self.master)
canvas.draw()
canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
canvas.mpl_connect("key_press_event", self.on_key_press)
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=lambda: self.switch_graphs(canvas, fig, ax))
self.button_switch.pack(side=BOTTOM)
# the def defines the key press event handler
def on_key_press(event):
key_press_handler(event, canvas, toolbar)
# This def quits the tkinter widget
def _quit(self):
self.master.quit() # stops mainloop
# This def switches between the two embedded graphs
def switch_graphs(self, fig, canvas, ax):
ax.clear()
self.embed_graph_two()
canvas.draw()
def main():
root = Tk()
matplotlibSwitchGraphs(root)
root.mainloop()
if __name__ == '__main__':
main()
此代码仍然不会用第二个图替换第一个图,而只是将第二个图放在第一个图之下.任何有关获取此代码以用第二个替换第一个图形的帮助将不胜感激.
我正在绘制的图表是OHLC烛台图表和带有体积叠加的OHLC烛台图表.不幸的是
self.canvas.draw()
draw_graph defs中的命令似乎不适用于此处.当我尝试显示图表时,我得到的只是一个空白图.这是我正在使用的代码,用于绘制烛台图表.这与draw_graph_one相对应.
def ohlc_daily_date_axis(self, stock_sym):
mondays = WeekdayLocator(MONDAY) # major ticks on the mondays
alldays = DayLocator() # minor ticks on the days
weekFormatter = DateFormatter('%b %d %Y') # e.g., Jan 12 2018
dayFormatter = DateFormatter('%d') # e.g., 12
quotes = get_stock_price_data_list_of_tuples(stock_sym)
graph_header_text = 'Daily OHLC Candlestick Chart: ' + stock_sym + ' Date Range: ' + str(
num2date(quotes[0][0]).date()) + ' - ' + str(num2date(quotes[-1][0]).date())
if len(quotes) == 0:
raise SystemExit
self.fig, self.ax = plt.subplots(figsize=(18, 5))
plt.subplots_adjust(bottom=0.2)
self.ax.xaxis.set_major_locator(mondays)
self.ax.xaxis.set_minor_locator(alldays)
self.ax.xaxis.set_major_formatter(weekFormatter)
# ax.xaxis.set_minor_formatter(dayFormatter)
plt.title(graph_header_text)
self.ax.set_ylabel('Share Price ($)', size=10)
# plot_day_summary(ax, quotes, ticksize=3)
candlestick_ohlc(self.ax, quotes, width=0.6)
self.ax.xaxis_date()
self.ax.autoscale_view()
plt.setp(plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right')
self.ax.format_coord = self.get_ohlc_from_date_xy
# ax.fmt_xdata = get_ohlc_from_date_x
#plt.show()
self.canvas.draw()
我如何修改它以显示数据?
解决方法:
包含Tk嵌入的新答案(来自其他答案的重大更改,因此添加新答案而不是编辑该答案).我将graph_one()和graph_two()移动到switch图形包装类中,并将它们重命名为draw_graph_one()和draw_graph_two().这两个新的类方法取代了embed_graph_one()和embed_graph_two()方法. embed()方法中的大多数内容都是重复的,因此被移动到config_window()方法,该方法在实例化类对象时调用.创建了一些类数据成员来捕获plt变量(例如canvas,ax,fig)并创建一个新的数据成员来跟踪当前显示的图形(graphIndex),以便我们可以在switch_graphs()时正确绘制正确的图形被调用(而不是每次“切换”时调用embed_graph_two(),如在原始代码中那样).或者,您可以从draw方法中取出t并使其成为类数据成员(如果t的值不更改).
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
import numpy as np
from tkinter import *
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
# Seperated out config of plot to just do it once
def config_plot():
fig, ax = plt.subplots()
ax.set(xlabel='time (s)', ylabel='voltage (mV)',
title='Graph One')
return (fig, ax)
class matplotlibSwitchGraphs:
def __init__(self, master):
self.master = master
self.frame = Frame(self.master)
self.fig, self.ax = config_plot()
self.graphIndex = 0
self.canvas = FigureCanvasTkAgg(self.fig, self.master)
self.config_window()
self.draw_graph_one()
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)
def draw_graph_one(self):
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2 * np.pi * t)
self.ax.clear() # clear current axes
self.ax.plot(t, s)
self.ax.set(title='Graph One')
self.canvas.draw()
def draw_graph_two(self):
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.cos(2 * np.pi * t)
self.ax.clear()
self.ax.plot(t, s)
self.ax.set(title='Graph Two')
self.canvas.draw()
def on_key_press(event):
print("you pressed {}".format(event.key))
key_press_handler(event, self.canvas, toolbar)
def _quit(self):
self.master.quit() # stops mainloop
def switch_graphs(self):
# Need to call the correct draw, whether we're on graph one or two
self.graphIndex = (self.graphIndex + 1 ) % 2
if self.graphIndex == 0:
self.draw_graph_one()
else:
self.draw_graph_two()
def main():
root = Tk()
matplotlibSwitchGraphs(root)
root.mainloop()
if __name__ == '__main__':
main()
输出(两个窗口,单击切换图形按钮时交替显示):
内容总结
以上是互联网集市为您收集整理的python – 如何使用按钮在matplotlib中的两个不同图形之间切换全部内容,希望文章能够帮你解决python – 如何使用按钮在matplotlib中的两个不同图形之间切换所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。