如何在Matplotlib中使用按钮在两个不同的图形之间切换

比尔·奥顿

我有两个不同的matplotlib图,我想在按下按钮时进行切换。当按下按钮时,我拥有的代码会将第二张图添加到第一张图下方,但是我希望它替换第一张图。这是一个有点类似的stackoverflow问题(如何更新嵌入到tkinter中的matplotlib?),但我似乎无法将其应用于我的情况。

我编写的图形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()进开关图包装类,并将其重命名为draw_graph_one()draw_graph_two()这两个新的类方法替换了embed_graph_one()embed_graph_two()方法。embed()方法中的大多数内容都是重复的,因此被移动到config_window()实例化类对象时调用方法。创建了一些类的数据成员捕捉PLT变量(例如canvasaxfig),并创建了一个新的数据成员来跟踪其当前显示图(graphIndex),以便我们能够正确得出正确的图形时switch_graphs()被调用(而不是调用embed_graph_two()每次进行“切换”(如原始代码一样)。(可选)您可以tdraw方法中取出并使其成为类数据成员(如果的值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()

输出(两个窗口,每当单击切换图按钮时交替显示): 在此处输入图片说明

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在两个按钮之间切换

来自分类Dev

如何在两个按钮之间切换并使用 angular 改变颜色

来自分类Dev

如何在HTML中使用<button>在两个CSS文档之间切换

来自分类Dev

使用按钮在两个 div 之间切换

来自分类Dev

如何在两个图像之间切换

来自分类Dev

如何在两个元素之间切换

来自分类Dev

如何在Swift中的两个按钮之间切换背景?

来自分类Dev

如何在两个不同的Xamarin Form页面之间切换?

来自分类Dev

如何在 vue.js 中使用 v-if 指令在两个组件之间切换?

来自分类Dev

如何在yii2中使用两个不同的模型登录或切换身份类?

来自分类Dev

如何使用按钮在两个div元素之间切换

来自分类Dev

如何使用Javascript代码通过按钮在两个图像之间切换?

来自分类Dev

如何使用angularjs中的两个单选按钮在div之间切换

来自分类Dev

如何使用javascript在两个不同的类名之间切换显示

来自分类Dev

如何使用作曲家在两个不同的PHP版本之间切换

来自分类Dev

如何在两个按钮中切换活动类并使用jQuery隐藏div?

来自分类Dev

在两个不同批次的张量之间切换

来自分类Dev

在两个不同元素之间切换类

来自分类Dev

单击按钮后,如何在SQL数据库的两个表之间切换?

来自分类Dev

如何在颤动中相同位置的两个不同小部件之间切换?

来自分类Dev

如何使用jQuery使用按钮动作在文本区域的两个状态之间切换

来自分类Dev

如何在用户仍然使用 SFML 持有键的情况下在精灵表的两个不同部分之间来回切换

来自分类Dev

如何使用JavaScript用一个按钮在两种不同的颜色之间切换

来自分类Dev

Swift iOS-如何在两个UIWindows之间切换/切换并设置keyWindow

来自分类Dev

如何将两个不同的 gif 绑定到 kivy 中的切换按钮?

来自分类Java

Android:使用XML为切换按钮指定两个不同的图像

来自分类Dev

使用复选框在两个不同的标签内容之间切换

来自分类Dev

如何在三个 div 和两个图标之间切换

来自分类Dev

使用Polymer在两个div之间切换

Related 相关文章

  1. 1

    如何在两个按钮之间切换

  2. 2

    如何在两个按钮之间切换并使用 angular 改变颜色

  3. 3

    如何在HTML中使用<button>在两个CSS文档之间切换

  4. 4

    使用按钮在两个 div 之间切换

  5. 5

    如何在两个图像之间切换

  6. 6

    如何在两个元素之间切换

  7. 7

    如何在Swift中的两个按钮之间切换背景?

  8. 8

    如何在两个不同的Xamarin Form页面之间切换?

  9. 9

    如何在 vue.js 中使用 v-if 指令在两个组件之间切换?

  10. 10

    如何在yii2中使用两个不同的模型登录或切换身份类?

  11. 11

    如何使用按钮在两个div元素之间切换

  12. 12

    如何使用Javascript代码通过按钮在两个图像之间切换?

  13. 13

    如何使用angularjs中的两个单选按钮在div之间切换

  14. 14

    如何使用javascript在两个不同的类名之间切换显示

  15. 15

    如何使用作曲家在两个不同的PHP版本之间切换

  16. 16

    如何在两个按钮中切换活动类并使用jQuery隐藏div?

  17. 17

    在两个不同批次的张量之间切换

  18. 18

    在两个不同元素之间切换类

  19. 19

    单击按钮后,如何在SQL数据库的两个表之间切换?

  20. 20

    如何在颤动中相同位置的两个不同小部件之间切换?

  21. 21

    如何使用jQuery使用按钮动作在文本区域的两个状态之间切换

  22. 22

    如何在用户仍然使用 SFML 持有键的情况下在精灵表的两个不同部分之间来回切换

  23. 23

    如何使用JavaScript用一个按钮在两种不同的颜色之间切换

  24. 24

    Swift iOS-如何在两个UIWindows之间切换/切换并设置keyWindow

  25. 25

    如何将两个不同的 gif 绑定到 kivy 中的切换按钮?

  26. 26

    Android:使用XML为切换按钮指定两个不同的图像

  27. 27

    使用复选框在两个不同的标签内容之间切换

  28. 28

    如何在三个 div 和两个图标之间切换

  29. 29

    使用Polymer在两个div之间切换

热门标签

归档