add Seaborn Scatter plot to tkinter gui - python

I want to add this scatter plot to my tkinter gui. I ran this on my jupyter notebook and it works but I am not sure how to implement it to the tkinter gui.
enter image description here
this is the window the graph should be
enter image description here
this is the code I have on my jupyter notebook:
### Import libraries
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
### Import dataset
players_df = pd.read_csv("player_locations.txt")
players_df
### Draw Seaborn Scatter Plot to find location between lat and long
sns.scatterplot(x = players_df["longitude"], y = players_df["latitude"], hue = players_df["Player"])
this is the code on my gui for the analysis window:
from tkinter import *
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import csv
import pandas as pd
import seaborn as sns
from matplotlib import animation
from matplotlib.animation import FuncAnimation
from matplotlib import style
players_df = pd.read_csv("player_locations.txt")
players_df
class addAnalysis(Toplevel):
def __init__(self):
Toplevel.__init__(self)
self.geometry("650x650+620+200")
self.title("Analysis")
self.resizable(False,False)
#Frames
self.top=Frame(self,height=150,bg='white')
self.top.pack(fill=X)
self.bottomFrame=Frame(self,height=500,bg='#f1dead')
self.bottomFrame.pack(fill=X)
#heading
self.heading = Label(self.top, text='Player Analysis', font='arial 25 bold',
fg='#000000', bg='white')
self.heading.place(x=230, y=60)
#buttons
graph_button = Button(self.bottomFrame,text=' Graph ',
font='arial 14 bold',command = self.plot)
graph_button.place(x=10,y=380)
exit_button = Button(self.bottomFrame,text=' Exit ',
font='arial 14 bold',command = self.destroy)
exit_button.place(x=10,y=440)
# this is the part where I implement the scatter plot
def plot():
# Draw Seaborn Scatter Plot to find location between lat and long
scatter = self.sns.scatterplot(x = players_df["longitude"], y = players_df["latitude"], hue = players_df["Player"])

I recently learned that tk can import PIL images. I needed to convert an numpy array with raw RGB data to tk and the advice was to use PIL.fromarray() to create a PIL image, then use ImageTk.PhotoImage() to import the PIL image into tk. I hope this information is useful to you.

Related

How to make a ipywidget button update a specific axis of a matplotlib figure?

How can I make a ipywidget button in a Jupyter notebook update a plot in a specific axis?
I already know how to make a button update a plot when using a single axis, like so:
import ipywidgets as widgets
from IPython.display import display
import matplotlib.pyplot as plt
import numpy as np
btn = widgets.Button(description='Click')
display(btn)
output = widgets.Output()
def on_click_fn(obj):
output.clear_output()
values = np.random.rand(10)
with output:
plt.plot(values)
plt.show()
btn.on_click(on_click_fn)
display(output)
In this example, clicking the button updates the plot and shows a new set of 10 random points. I thought it would be simple to extend this to updating a specific axis, and attempted the following:
import ipywidgets as widgets
from IPython.display import display
import matplotlib.pyplot as plt
import numpy as np
btn = widgets.Button(description='Click')
display(btn)
output = widgets.Output()
fig, ax = plt.subplots(ncols=2)
def on_click_fn(obj):
output.clear_output()
values = np.random.rand(10)
with output:
ax[0].plot(values)
plt.show()
btn.on_click(on_click_fn)
display(output)
However, clicking the button in this example does not seem to do anything. I tried different combinations of adding/removing the plt.show() call, using fig.draw() instead, using fig.canvas.draw_idle(), etc, without much success. What's the correct, least "hacky" way of accomplishing this?
Note: This question is only about how to make a button update a plot, like my first example, instead of making the button update a specific axis only.
with this code
import ipywidgets as widgets
from IPython.display import display
import matplotlib.pyplot as plt
import numpy as np
%matplotlib widget
btn = widgets.Button(description='Click')
display(btn)
output = widgets.Output()
fig, ax = plt.subplots(ncols=2)
def on_click_fn(obj):
output.clear_output()
values = np.random.rand(10)
with output:
ax[0].plot(values)
plt.show()
btn.on_click(on_click_fn)
display(output)
I got this output

How to display a pandas datafarme in tkinter

I created a pandas dataframe from a csv file in python. How do I display this dataframe in a tkinter window.
import pandas as pd
methods = pd.read_csv('metode.csv')
methods = methods.drop(methods.columns[[0]], axis=1)
Here an example of creating a csv file with square roots; reading the the csv and plotting it in tkinter. To capture the matplotlib figure you have to use FigureCanvasTkAgg and link the mpl plot with the tkinter figure with ax=tk_ax as in the below example.
import pandas as pd
import tkinter as tk
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
# create the csv file with square roots
squareroots = [(i, i**0.5) for i in range(0, 100)]
squareroot_df = pd.DataFrame(squareroots, columns=['i', 'i^0.5'])
squareroot_df.to_csv('temp_squareroots.csv', index=False)
# set up the tkinter GUI
root = tk.Tk()
fig, tk_ax = plt.subplots(figsize=(10, 10))
mpl_plot = FigureCanvasTkAgg(fig, root)
mpl_plot.get_tk_widget().pack()
# read the csv file
square_roots_df = pd.read_csv('temp_squareroots.csv')
# plot the values in the data frame and invert the x-axis
mpl_ax = square_roots_df.plot(x='i', y='i^0.5', color='firebrick', ax=tk_ax)
mpl_ax.invert_xaxis()
root.mainloop()
In any case it is just a lot easier to just plot in matplotlib:
import pandas as pd
import matplotlib.pyplot as plt
squareroots = [(i, i**0.5) for i in range(0, 100)]
squareroot_df = pd.DataFrame(squareroots, columns=['i', 'i^0.5'])
squareroot_df.to_csv('temp_squareroots.csv', index=False)
square_roots_df = pd.read_csv('temp_squareroots.csv')
ax = square_roots_df.plot(x='i', y='i^0.5', color='firebrick')
ax.invert_xaxis()
plt.show()
Note I added mpl_ax.invert_xaxis() just to show you can adjust your plot manipulating the mpl_ax object. (see Matplotlib documentation)

Embedding seaborn clustermap into tkinter window

I'm attempting to display a seaborn clustermap in a tkinter window.
I can embed seaborn heatmaps; however, clustermaps fail to appear in the tkinter window and an empty seaborn frame appears instead.
#Libraries
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import tkinter
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
#Returns plot for tkinter to display
def create_plot():
#creates dataset
data = np.random.rand(50,11)
#Defines plot
plot, ax = plt.subplots(figsize=(11, 9))
#Does work - Outputs heatmap
#sns.heatmap(data, cmap='YlGnBu')
#Doesn't work - Should output clustermap
sns.clustermap(data,cmap='YlGnBu',metric = 'correlation',z_score=0)
return plot
#Generating tkinter window
root = tkinter.Tk()
figure = create_plot()
canvas = FigureCanvasTkAgg(figure, master=root)
canvas.draw()
canvas.get_tk_widget().pack()
tkinter.mainloop()
The clustermap can be correctly displayed inline with the following code:
%matplotlib inline
data = np.random.rand(50,11)
sns.clustermap(data,cmap='YlGnBu',metric = 'correlation',z_score=0)
Is there something different about clustermaps, how can they be embedded?
clustermap creates its own figure. So you need to return this figure to use it elsewhere.
#Libraries
import numpy as np
import seaborn as sns
import tkinter
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
#Returns plot for tkinter to display
def create_plot():
data = np.random.rand(50,11)
g = sns.clustermap(data,cmap='YlGnBu',metric = 'correlation',z_score=0)
return g.fig
#Generating tkinter window
root = tkinter.Tk()
figure = create_plot()
canvas = FigureCanvasTkAgg(figure, master=root)
canvas.draw()
canvas.get_tk_widget().pack()
tkinter.mainloop()
But be aware that seaborn creates a pyplot figure. Embedding a pyplot figure in a custom GUI may cause problems (note how none of the examples from the matplotlib page on embedding use pyplot!).

Embedding matplotlib into tkinter canvas opens two windows

The following code I am working on in not behaving the way I wish it to. I have embedded a matplotlib graph into a tkinter canvas. The program opens up two windows, one of which functions properly, and one of which is not necessary.I am not sure how to fix this. Here is the code, please ignore the unnecessary imports :)
import numpy as np
import sys
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib as mpl
from matplotlib import cm
from numpy.random import random
from matplotlib.widgets import Button
import matplotlib.colors
import tkinter as tk
import matplotlib.backends.tkagg as tkagg
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
DEBUG_MODE = False #Debug mode - True = ON
MATRIX_WIDTH = 50
MATRIX_HEIGHT = 50
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
LED_COUNT = MATRIX_WIDTH * MATRIX_HEIGHT
REFRESH_RATE = 30 #REFRESH_RATE used to control FuncAnimation interval
MATRIX = random((50,50)) #Fills MATRIX as not to be null for first print
plt.rcParams['toolbar'] = 'None' #Disables matplotlib toolbar
fig = plt.figure(figsize=(3,3)) #'figsize' measured in inches
im = plt.imshow(MATRIX, interpolation='nearest', cmap=cm.Spectral)
plt.axis('off') #Turns off x, y axis
def data_gen(): #Generates amd populates MATRIX with pattern data
while True:
MATRIX = random((MATRIX_WIDTH, MATRIX_HEIGHT))
yield MATRIX
if (DEBUG_MODE): print("MATRIX yeilded")
def update(data): #Updates/prints new MATRIX from data_gen()
im.set_array(data)
if (DEBUG_MODE): print("Updated data")
root = tk.Tk()
label = tk.Label(root,text="Matrix Program").grid(column=0, row=0)
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.get_tk_widget().grid(column=0,row=1)
ani = animation.FuncAnimation(fig, update, data_gen, interval=REFRESH_RATE)
plt.show()
What needs to be done to this code so that it opens only one canvas from tkinter with the live matplotlib graph embedded?
How can I set the size of the canvas?
Do not call plt.show() if you want to show your figure inside a tk GUI. Best do not use pyplot at all when embedding.
On the other hand, you probably want to start the mainloop, tk.mainloop(), at some point.
Refer to the matplotlib example on how to embedd a matplotlib figure into tk.

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

Categories

Resources