在两个不同的tkinter嵌入式matplotlib烛台图表之间切换时,数据不出现 [英] While switching between two different tkinter embedded matplotlib candlestick charts data does not appear

查看:62
本文介绍了在两个不同的tkinter嵌入式matplotlib烛台图表之间切换时,数据不出现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是对

解决方案

以下代码现在可以正常使用

我清理了这段代码,并解决了部分问题.我更改了config_plot,以便仅配置了无花果,并在各自的图中创建了轴.我对其进行了更改,以使两个图形上的每个轴都是类实例,并且具有唯一的名称,然后将axis.clear()语句移动到了正确的位置.事实证明,axis.clear() 应该是axis.remove().完成所有这些更改后,代码即可正常工作

  import matplotlibmatplotlib.use("TkAgg")导入matplotlib.pyplot作为plt从 tkinter 导入 *从matplotlib.backends.backend_tkagg导入(FigureCanvasTkAgg,NavigationToolbar2Tk)从 matplotlib.backend_bases 导入 key_press_handler从 matplotlib.dates 导入 date2num, num2date从 matplotlib.dates 导入 DateFormatter、WeekdayLocator、DayLocator,周一从 mpl_finance 进口烛台_ohlc从日期时间导入日期时间#分离出剧情的配置只做一次def config_plot():无花果= plt.figure(figsize =(18,5))返回(图)matplotlibStock类:def __init __(自己,主人):self.master = 主人self.frame = Frame(self.master)self.fig = config_plot()self.graphIndex = 0self.canvas = FigureCanvasTkAgg(self.fig, self.master)self.config_window()self.ohlc_daily_date_axis(self.fig)self.frame.pack(expand=YES,fill=BOTH)defquotes_info(self):返回 [(737042.0, 2.72, 2.78, 2.6815, 2.74, 414378.0),(737045.0, 2.71, 2.77, 2.57, 2.63, 578841.0),(737046.0, 2.64, 2.64, 2.4228, 2.47, 1451450.0),(737047.0、2.9、3.15、2.7、2.96、7230260.0),(737048.0、2.92、3.29、2.67、2.83、2784110.0),(737049.0、2.78、2.82、2.4701、2.51、822776.0),(737052.0、2.56、2.6344、2.49、2.5、278883.0),(737054.0、2.5、2.619、2.34、2.6、606002.0),(737055.0, 2.57, 2.63, 2.45, 2.57, 1295820.0),(737056.0, 2.57, 2.75, 2.51, 2.65, 435838.0)]def config_window(self):self.canvas.mpl_connect("key_press_event",self.on_key_press)工具栏= NavigationToolbar2Tk(self.canvas,self.master)工具栏.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="切换图表",命令= self.switch_graphs)self.button_switch.pack(side =底部)plt.subplots_adjust(bottom = 0.2)def ohlc_daily_date_axis(自己,无花果):报价= self.quotes_info()self.ax = fig.subplots()尝试:self.ax1.remove() # 清除当前坐标轴self.ax2.remove()除了AttributeError:经过mondays = WeekdayLocator(MONDAY) # 星期一的主要刻度alldays = DayLocator()#这些天的小滴答weekFormatter = DateFormatter('%b%d%Y')#例如2018年1月12日dayFormatter = DateFormatter('%d')#例如12self.ax.xaxis.set_major_locator(星期一)self.ax.xaxis.set_minor_locator(全天)self.ax.xaxis.set_major_formatter(weekFormatter)#ax.xaxis.set_minor_formatter(dayFormatter)self.ax.set_ylabel('股价($)', size=10)plt.title('无音量叠加')烛台_ohlc(self.ax,报价,宽度= 0.6)plt.setp(plt.gca().get_xticklabels(),旋转= 45,水平对齐='右')self.canvas.draw()def ohlc_daily_date_axis_w_vol(自己,无花果):报价= self.quotes_info()date_pos = []日期_负 = []vols_pos = []vols_neg = []对于范围内的我(len(quotes)):如果引号[i][1] - 引号[i][4] <= 0:date_pos.append(quotes[i][0])vols_pos.append(quotes[i][5])如果引号[i][1] - 引号[i][4] >0:date_neg.append(quotes [i] [0])vols_neg.append(quotes [i] [5])self.ax.remove()self.ax1 = plt.subplot2grid((5, 4), (0, 0), rowspan=4,colspan = 4)plt.subplots_adjust(bottom = 0.2)self.ax1.set_ylabel('股价($)',大小= 10)plt.title('有音量叠加')# 开始卷代码self.ax2 = plt.subplot2grid((5, 4), (4, 0), sharex=self.ax1,rowspan = 1,colspan = 4)self.ax2.bar(dates_pos,vols_pos,color ='green',width = 1,对齐 =中心")self.ax2.bar(dates_neg, vols_neg, color='red', width=1,对齐 =中心")标签= [self.ax2.get_yticks()中l的int(l)]self.ax2.axes.yaxis.set_ticklabels(labels)yticks = self.ax2.get_yticks()self.ax2.yaxis.tick_right()self.ax2.set_yticks(yticks)self.ax2.yaxis.set_label_position("right")self.ax2.set_ylabel('Volume',size = 10)烛台_ohlc(self.ax1,报价,宽度= 0.6)self.ax1.xaxis_date()self.ax1.autoscale_view()plt.setp(plt.gca().get_xticklabels(),旋转=45,水平对齐='右')# 接下来的 2 行是 vol 行plt.setp(self.ax1.get_xticklabels(),可见=假)plt.subplots_adjust(hspace=0)self.canvas.draw()def on_key_press(事件):key_press_handler(事件,画布,工具栏)def _quit(self):self.master.quit() # 停止主循环def switch_graphs(self):# 需要调用正确的绘图,无论我们是在图一还是图二self.graphIndex =(self.graphIndex +1)%2如果 self.graphIndex == 0:self.ohlc_daily_date_axis(self.fig)别的:self.ohlc_daily_date_axis_w_vol(self.fig)定义主():根= Tk()matplotlibStock(根)root.mainloop()如果 __name__ == '__main__':主要的()

This is a follow up to the question posted at How do I use a button to switch between two different graphs in matplotlib
Many thanks to endyd for that solution.

The code at that url works perfectly if the graphs being switched between are typical matplotlib graphs but I am attempting to use a button to switch between two graphs where one is a candlestick chart without a volume overlay and the second is the same candlestick chart but with a volume overlay. Unfortunately I have been unable to get this code to display the candlestick data or the volume data using the code from the shown url.

The matplotlib code for the candlestick code is from mpl_finance and is located at https://github.com/matplotlib/mpl_finance/blob/master/mpl_finance.py

Here is my complete code that embeds the two candlestick charts (without and with the volume overlay) into a tkinter widget and which allows the use of a button to switch between the two graphs per the code from my initial question:

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
from SQL_code import connectToSQL
from matplotlib.dates import date2num, num2date
from matplotlib.dates import DateFormatter, WeekdayLocator, 
DayLocator, MONDAY
from mpl_finance import candlestick_ohlc
from datetime import datetime

# Separated out config of plot to just do it once
def config_plot():
    fig, ax = plt.subplots(figsize=(18, 5))
    #ax.set(xlabel='time (s)', ylabel='voltage (mV)', title='Graph 
One')
    return (fig, ax)

class matplotlibStock:
    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.ohlc_daily_date_axis()
        self.frame.pack(expand=YES, fill=BOTH)

    def quotes_info(self):
        quotes = [(737042.0, 2.72, 2.78, 2.6815, 2.74, 414378.0),
                  (737045.0, 2.71, 2.77, 2.57, 2.63, 578841.0),
                  (737046.0, 2.64, 2.64, 2.4228, 2.47, 1451450.0),
                  (737047.0, 2.9, 3.15, 2.7, 2.96, 7230260.0),
                  (737048.0, 2.92, 3.29, 2.67, 2.83, 2784110.0),
                  (737049.0, 2.78, 2.82, 2.4701, 2.51, 822776.0),
                  (737052.0, 2.56, 2.6344, 2.49, 2.5, 278883.0),
                  (737054.0, 2.5, 2.619, 2.34, 2.6, 606002.0),
                  (737055.0, 2.57, 2.63, 2.45, 2.57, 1295820.0),
                  (737056.0, 2.57, 2.75, 2.51, 2.65, 435838.0)]

        return quotes

    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 ohlc_daily_date_axis(self):
        quotes = self.quotes_info()
        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



        #self.fig, self.ax = plt.subplots(figsize=(18, 5))
        self.ax.clear()  # clear current axes
        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 One')
        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')

        #plt.show()
        self.canvas.draw()

    def ohlc_daily_date_axis_w_vol(self):
        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 = self.quotes_info()
        dates_pos = []
        dates_neg = []
        vols_pos = []
        vols_neg = []
        for i in range(len(quotes)):
            if quotes[i][1] - quotes[i][4] <= 0:
                dates_pos.append(quotes[i][0])
                vols_pos.append(quotes[i][5])
            if quotes[i][1] - quotes[i][4] > 0:
                dates_neg.append(quotes[i][0])
                vols_neg.append(quotes[i][5])


        self.ax.clear()  # clear current axes
        self.fig = plt.figure(figsize=(18, 5))
        self.ax = plt.subplot2grid((5, 4), (0, 0), rowspan=4, 
colspan=4)
        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)
        self.ax.set_ylabel('Share Price ($)', size=10)
        plt.title("Graph Two")

        # begin volume code
        self.ax2 = plt.subplot2grid((5, 4), (4, 0), sharex=self.ax, 
rowspan=1, colspan=4)

        self.ax2.bar(dates_pos, vols_pos, color='green', width=1, 
align='center')
        self.ax2.bar(dates_neg, vols_neg, color='red', width=1, 
align='center')
        labels = [int(l) for l in self.ax2.get_yticks()]
        self.ax2.axes.yaxis.set_ticklabels(labels)

        yticks = self.ax2.get_yticks()
        self.ax2.yaxis.tick_right()
        self.ax2.set_yticks(yticks)

        self.ax2.yaxis.set_label_position("right")
        self.ax2.set_ylabel('Volume', size=10)

        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')

        # these next 2 lines are vol lines
        plt.setp(self.ax.get_xticklabels(), visible=False)
        plt.subplots_adjust(hspace=0)

        #plt.show()
        self.canvas.draw()


    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):
        # 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.ohlc_daily_date_axis()
        else:
            self.ohlc_daily_date_axis_w_vol()



def main():
    root = Tk()
    matplotlibStock(root)
    root.mainloop()

if __name__ == '__main__':
    main()

I am encountering two problems in using this code with my candlestick charts. The first is that the data does not display and I believe this is somehow related to the

self.canvas.draw()

command. The second problem is that my candlestick chart with the volume overlay has two sets of axis, one for the candlestick OHLC data and the second for the volume data, which does not seem workable using the config_plot def. Any advice on resolving these issues is greatly appreciated.

The following is code that shows just how the candlestick chart with the volume overlay looks. This code uses two axes, one for the candlestick chart and the second for the volume overlay and then combines them into one figure.

For general information purposes an OHLC candlestick chart shows stock prices where for every date the open (O), high (H), low (L) and close (C) are all plotted. The volume overlay is a separate graph below the candlestick chart that plots the number of shares (volume) traded for that date. It is typical when viewing stock charts that a candlestick chart is used to view the changes in a stocks price on a day to day basis where the stocks volume can be made visible or not visible.

import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter, WeekdayLocator, 
DayLocator, MONDAY
from mpl_finance import candlestick_ohlc




def quotes_info():
    return [(737042.0, 2.72, 2.78, 2.6815, 2.74, 414378.0),
            (737045.0, 2.71, 2.77, 2.57, 2.63, 578841.0),
            (737046.0, 2.64, 2.64, 2.4228, 2.47, 1451450.0),
            (737047.0, 2.9, 3.15, 2.7, 2.96, 7230260.0),
            (737048.0, 2.92, 3.29, 2.67, 2.83, 2784110.0),
            (737049.0, 2.78, 2.82, 2.4701, 2.51, 822776.0),
            (737052.0, 2.56, 2.6344, 2.49, 2.5, 278883.0),
            (737054.0, 2.5, 2.619, 2.34, 2.6, 606002.0),
            (737055.0, 2.57, 2.63, 2.45, 2.57, 1295820.0),
            (737056.0, 2.57, 2.75, 2.51, 2.65, 435838.0)]





def ohlc_daily_date_axis_w_vol():
    mondays = WeekdayLocator(MONDAY)        
    alldays = DayLocator()              
    weekFormatter = DateFormatter('%b %d %Y')  
    dayFormatter = DateFormatter('%d')      

    quotes = quotes_info()
    dates_pos = []
    dates_neg = []
    vols_pos = []
    vols_neg = []
    for i in range(len(quotes)):
        if quotes[i][1] - quotes[i][4] <= 0:
            dates_pos.append(quotes[i][0])
            vols_pos.append(quotes[i][5])
        if quotes[i][1] - quotes[i][4] > 0:
            dates_neg.append(quotes[i][0])
            vols_neg.append(quotes[i][5])



    fig = plt.figure(figsize=(18,5))
    ax = plt.subplot2grid((5, 4), (0, 0), rowspan=4, colspan=4)
    plt.subplots_adjust(bottom=0.2)
    ax.xaxis.set_major_locator(mondays)
    ax.xaxis.set_minor_locator(alldays)
    ax.xaxis.set_major_formatter(weekFormatter)
    ax.set_ylabel('Share Price ($)', size=10)


    # begin volume code
    ax2 = plt.subplot2grid((5, 4), (4, 0), sharex=ax, rowspan=1, 
colspan=4)

    #ax2.bar(dates, vols)
    ax2.bar(dates_pos, vols_pos, color='green', width=1, 
align='center')
    ax2.bar(dates_neg, vols_neg, color='red', width=1, align='center')
    labels = [int(l) for l in ax2.get_yticks()]
    ax2.axes.yaxis.set_ticklabels(labels)

    yticks = ax2.get_yticks()
    ax2.yaxis.tick_right()
    ax2.set_yticks(yticks)

    ax2.yaxis.set_label_position("right")
    ax2.set_ylabel('Volume', size=10)

    candlestick_ohlc(ax, quotes, width=0.6)

    ax.xaxis_date()
    ax.autoscale_view()
    plt.setp(plt.gca().get_xticklabels(), rotation=45, 
horizontalalignment='right')

    # these next 2 lines are vol lines
    plt.setp(ax.get_xticklabels(), visible=False)
    plt.subplots_adjust(hspace=0)



    plt.show()




if __name__ == '__main__':
    ohlc_daily_date_axis_w_vol()

解决方案

The following code now works correctly

I cleaned up this code and resolved part of the problem. I changed config_plot so that only the fig was being configured and created the axes inside their respective graphs. I changed it so that each axis on the two graphs were class instances and had a unique name and moved the axis.clear() statements to the correct locations. It turns out that axis.clear() should be axis.remove(). With all these changes in place the code works correctly

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
from matplotlib.dates import date2num, num2date
from matplotlib.dates import DateFormatter, WeekdayLocator, DayLocator, 
MONDAY
from mpl_finance import candlestick_ohlc
from datetime import datetime

# Separated out config of plot to just do it once
def config_plot():
    fig = plt.figure(figsize=(18, 5))
    return (fig)

class matplotlibStock:
    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.ohlc_daily_date_axis(self.fig)
        self.frame.pack(expand=YES, fill=BOTH)

    def quotes_info(self):
        return [(737042.0, 2.72, 2.78, 2.6815, 2.74, 414378.0),
                  (737045.0, 2.71, 2.77, 2.57, 2.63, 578841.0),
                  (737046.0, 2.64, 2.64, 2.4228, 2.47, 1451450.0),
                  (737047.0, 2.9, 3.15, 2.7, 2.96, 7230260.0),
                  (737048.0, 2.92, 3.29, 2.67, 2.83, 2784110.0),
                  (737049.0, 2.78, 2.82, 2.4701, 2.51, 822776.0),
                  (737052.0, 2.56, 2.6344, 2.49, 2.5, 278883.0),
                  (737054.0, 2.5, 2.619, 2.34, 2.6, 606002.0),
                  (737055.0, 2.57, 2.63, 2.45, 2.57, 1295820.0),
                  (737056.0, 2.57, 2.75, 2.51, 2.65, 435838.0)]

    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)


    def ohlc_daily_date_axis(self, fig):
        quotes = self.quotes_info()

        self.ax = fig.subplots()
        try:
            self.ax1.remove()  # clear current axes
            self.ax2.remove()
        except AttributeError:
            pass


        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
        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)
        self.ax.set_ylabel('Share Price ($)', size=10)
        plt.title('Without Volume Overlay')

        candlestick_ohlc(self.ax, quotes, width=0.6)
        plt.setp(plt.gca().get_xticklabels(), rotation=45, 
horizontalalignment='right')

        self.canvas.draw()


    def ohlc_daily_date_axis_w_vol(self, fig):
        quotes = self.quotes_info()
        dates_pos = []
        dates_neg = []
        vols_pos = []
        vols_neg = []
        for i in range(len(quotes)):
            if quotes[i][1] - quotes[i][4] <= 0:
                dates_pos.append(quotes[i][0])
                vols_pos.append(quotes[i][5])
            if quotes[i][1] - quotes[i][4] > 0:
                dates_neg.append(quotes[i][0])
                vols_neg.append(quotes[i][5])

        self.ax.remove()


        self.ax1 = plt.subplot2grid((5, 4), (0, 0), rowspan=4, 
colspan=4)
        plt.subplots_adjust(bottom=0.2)
        self.ax1.set_ylabel('Share Price ($)', size=10)
        plt.title('With Volume Overlay')


        # begin volume code
        self.ax2 = plt.subplot2grid((5, 4), (4, 0), sharex=self.ax1, 
rowspan=1, colspan=4)

        self.ax2.bar(dates_pos, vols_pos, color='green', width=1, 
align='center')
        self.ax2.bar(dates_neg, vols_neg, color='red', width=1, 
align='center')
        labels = [int(l) for l in self.ax2.get_yticks()]
        self.ax2.axes.yaxis.set_ticklabels(labels)

        yticks = self.ax2.get_yticks()
        self.ax2.yaxis.tick_right()
        self.ax2.set_yticks(yticks)

        self.ax2.yaxis.set_label_position("right")
        self.ax2.set_ylabel('Volume', size=10)

        candlestick_ohlc(self.ax1, quotes, width=0.6)

        self.ax1.xaxis_date()
        self.ax1.autoscale_view()
        plt.setp(plt.gca().get_xticklabels(), rotation=45, 
horizontalalignment='right')

        # these next 2 lines are vol lines
        plt.setp(self.ax1.get_xticklabels(), visible=False)
        plt.subplots_adjust(hspace=0)

        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):
        # 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.ohlc_daily_date_axis(self.fig)
        else:
            self.ohlc_daily_date_axis_w_vol(self.fig)



def main():
    root = Tk()
    matplotlibStock(root)
    root.mainloop()

if __name__ == '__main__':
    main()  

这篇关于在两个不同的tkinter嵌入式matplotlib烛台图表之间切换时,数据不出现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆