pythonmatplotlibtkinterseabornsis

How can I integrate Seaborn plot into Tkinter GUI


I am trying to plot using Seaborn in Tkinter. My approaches so far were different variations of this and I could not get it to work.

I tried the matplotlib.use("Agg"), which works fine one the normal Matplotlib graphs on the page but doesn't seem to work on the Seaborn plots

matplotlib.use("TkAgg") # 'Agg' doesnt work either
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import seaborn as sns
import tkinter as tk

def graphspage():
    pf = tk.Tk()
    pf.geometry("1000x800")


### Works
    f = Figure(figsize=(5, 5), dpi=100)
    a = f.add_subplot(111)
    a.plot(df['date'],daily_drawdown, 'b-',df['date'], daily_drawdownbm, 'k-', linewidth=1)
    f.tight_layout()

    canvas = FigureCanvasTkAgg(f,pf)
    canvas.get_tk_widget().grid(row=1,column=1)

### Doesnt Work
    pct = diststats()[4]
    pctbm = diststats()[5]
    f = Figure(figsize=(5, 5), dpi=100)
    a = f.add_subplot(111)
    a.sns.distplot(pct,label = 'Portfolio')
    a.sns.distplot(pctbm,axlabel='Distribution of returns',label='Benchmark')

    canvas = FigureCanvasTkAgg(f,pf)
    canvas.get_tk_widget().grid(row=2,column=1)

graphspage()

Solution

  • The OP's original code only lacked a canvas.draw(), if I'm not mistaken. This has also been indicated by furas. I recently found it difficult to find a full example of how to draw with Seaborn on a Tkinter GUI and especially, how to redraw on the canvas.

    So, let me give you a fully working but mininmal snippet for a program that initially draws and redraws on every keypress.

    import tkinter
    from typing import Callable
    
    import numpy as np
    import seaborn as sns
    from matplotlib.backend_bases import key_press_handler
    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
    from matplotlib.figure import Figure
    
    
    def init_gui(root, update_function: Callable) -> FigureCanvasTkAgg:
        def event_key_press(event):
            print("you pressed {}".format(event.key))
            update_function()
            key_press_handler(event, canvas)
    
        # create empty figure and draw
        init_figure = create_figure()
        canvas = FigureCanvasTkAgg(init_figure, master=root)
        canvas.draw()
        canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)
        # call key press event
        canvas.mpl_connect("key_press_event", event_key_press)
        return canvas
    
    
    def create_figure() -> Figure:
        # generate some data
        matrix = np.random.randint(20, size=(10, 10))
        # plot the data
        figure = Figure(figsize=(6, 6))
        ax = figure.subplots()
        sns.heatmap(matrix, square=True, cbar=False, ax=ax)
        return figure
    
    
    def redraw_figure():
        figure = create_figure()
        canvas.figure = figure
        canvas.draw()
    
    
    sns.set()
    root = tkinter.Tk()
    canvas = init_gui(root, update_function=redraw_figure)
    
    tkinter.mainloop()
    

    I used some example code provided by matplotlib.

    This is how the code above looks when executed and when pressing some keys:

    Preview of Tkinter with Seaborn plot