Search code examples
pythonpandasmatplotlibtkinterembed

Python: Embed pandas plot in Tkinter GUI


I'm writing an application using pandas DataFrames in Python 2.7. I need to plot columns of my DataFrames to a Tkinter window. I know that I can plot pandas DataFrames columns using the built-in plot method on the DataFrame or Series (that is just a wrapper of the matplotlib plot function), like so:

import pandas as pd
df = pd.DataFrame({'one':[2,4,6,8], 'two':[3,5,7,9]})
df.plot('one')

Also, I figured out how to plot to a Tkinter GUI window using matplotlib:

import matplotlib
matplotlib.use('TkAgg')
from numpy import arange, sin, pi
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import pandas as pd
import Tkinter as tk
import ttk

root = tk.Tk()
#-------------------------------------------------------------------------------
lf = ttk.Labelframe(root, text='Plot Area')
lf.grid(row=0, column=0, sticky='nwes', padx=3, pady=3)

f = Figure(figsize=(5,4), dpi=100)
a = f.add_subplot(111)
t = arange(0.0,3.0,0.01)
s = sin(2*pi*t)
a.plot(t,s)

dataPlot = FigureCanvasTkAgg(f, master=lf)
dataPlot.show()
dataPlot.get_tk_widget().grid(row=0, column=0)
#-------------------------------------------------------------------------------
root.mainloop()

This all works as expected. What I want to do is have the pandas.DataFrame.plot() output on a Tkinter window, e.g. in the Labelframe as above. I can't get this to work. If possible, I do not want to use matplotlibs plot tools, as the pandas plot tools suit my needs much better. Is there a way to combine pandas plot() with Tkinter? Basically instead of this line:

dataPlot = FigureCanvasTkAgg(f, master=lf)
dataPlot.show()

I need this:

dataPlot = FigureCanvasTkAgg(df.plot('one'), master=lf)
dataPlot.show()

Solution

  • pandas uses matplotlib for plotting. Most pandas plotting functionality takes an ax kwarg that specifies the axes object that will be used. There are a few pandas functions that can't be used this way, and will always create their own figure/axes using pyplot. (e.g. scatter_matrix)

    For a simple case based on your example, however:

    import matplotlib
    import numpy as np
    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
    from matplotlib.figure import Figure
    import pandas as pd
    import Tkinter as tk
    import ttk
    
    root = tk.Tk()
    
    lf = ttk.Labelframe(root, text='Plot Area')
    lf.grid(row=0, column=0, sticky='nwes', padx=3, pady=3)
    
    t = np.arange(0.0,3.0,0.01)
    df = pd.DataFrame({'t':t, 's':np.sin(2*np.pi*t)})
    
    fig = Figure(figsize=(5,4), dpi=100)
    ax = fig.add_subplot(111)
    
    df.plot(x='t', y='s', ax=ax)
    
    canvas = FigureCanvasTkAgg(fig, master=lf)
    canvas.show()
    canvas.get_tk_widget().grid(row=0, column=0)
    
    root.mainloop()