Matplotlib Scatter plot interactivity not working - python-3.x

Until this morning I was able to display labels information when hovering the dots on a scatter plot.
Now, if I run the following code it does not display any error but the interactivity is not working and it looks like mplconnect or mlpcursors are completely ignored.
I've tried the same code under windows and Fedora.
Not understanding what's going on.
from matplotlib.pyplot import figure, show
import numpy as npy
from numpy.random import rand
x, y, c, s = rand(4, 100)
def onpick3(event):
ind = event.ind
print('onpick3 scatter:', ind, npy.take(x, ind), npy.take(y, ind))
fig = figure()
ax1 = fig.add_subplot(111)
col = ax1.scatter(x, y, 100*s, c, picker=True)
#fig.savefig('pscoll.eps')
fig.canvas.mpl_connect('pick_event', onpick3)
show()
Or
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)
x = np.random.rand(15)
y = np.random.rand(15)
names = np.array(list("ABCDEFGHIJKLMNO"))
c = np.random.randint(1,5,size=15)
norm = plt.Normalize(1,4)
cmap = plt.cm.RdYlGn
fig,ax = plt.subplots()
sc = plt.scatter(x,y,c=c, s=100, cmap=cmap, norm=norm)
annot = ax.annotate("", xy=(0,0), xytext=(20,20),textcoords="offset points",
bbox=dict(boxstyle="round", fc="w"),
arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)
def update_annot(ind):
pos = sc.get_offsets()[ind["ind"][0]]
annot.xy = pos
text = "{}, {}".format(" ".join(list(map(str,ind["ind"]))),
" ".join([names[n] for n in ind["ind"]]))
annot.set_text(text)
annot.get_bbox_patch().set_facecolor(cmap(norm(c[ind["ind"][0]])))
annot.get_bbox_patch().set_alpha(0.4)
def hover(event):
vis = annot.get_visible()
if event.inaxes == ax:
cont, ind = sc.contains(event)
if cont:
update_annot(ind)
annot.set_visible(True)
fig.canvas.draw_idle()
else:
if vis:
annot.set_visible(False)
fig.canvas.draw_idle()
fig.canvas.mpl_connect("motion_notify_event", hover)
plt.show()
This is not my code, I've copied and pasted it from a website but the behavior is the same.

Plotly express solves the problem
import plotly.express as px
alpha = data[data['Ticker']==focus].V1
gamma = data[data['Ticker']==focus].V2
fig = px.scatter(data, x='V1', y='V2', color=Colors.Market_Cap, hover_data=["Ticker"] )
fig.add_shape(type="circle",
xref="x", yref="y",
x0=int(alpha-3), y0=int(gamma-3), x1=int(alpha+3), y1=int(gamma+3),
line_color="LightSeaGreen",
)
fig.show()

Related

Moving the plot regrading to the offset

Dears,
I wrote this code to calculate the distance between two mouse clicks on the plot. Now I am trying to move the plot to the left or to the right with regards to the calculated offset so that the two plots are exactly match. any idea how to achieve that? I tried to add and subtract normally but it did not work.
import matplotlib.pyplot as plt
from matplotlib.widgets import Cursor
import mplcursors
from math import sqrt
import numpy as np
import tkinter as tk
from tkinter import simpledialog
class DistancePlot:
def __init__(self):
ROOT = tk.Tk()
ROOT.withdraw()
ROOT.geometry("500x200")
#my_frame = Frame(ROOT)
#my_frame.pack(fill="both", expand=True)
USER_INP = (simpledialog.askinteger(title="Plot dialig",
prompt="Enter the number of the plots "))
if USER_INP is not None:
def f(x):
return np.sin(x) + np.random.normal(scale=0.1, size=len(x))
self.x = np.linspace(1, 10)
self.fig, self.ax= plt.subplots()
for i in range(USER_INP):
plt.plot(self.x, f(self.x))
self.ax.set_xlabel('X-axis')
self.ax.set_ylabel('Y-axis')
self.d1 = (0.0, 0.0)
self.d2 = (0.0, 0.0)
self.first_click = True
self.cursor=Cursor(self.ax, horizOn=True, vertOn=True, color='black', linewidth=1.0)
self.fig.canvas.mpl_connect('button_press_event', self.onclick)
mplcursors.cursor(hover=True)
plt.show()
else:
def quit(self):
self.ROOT.destroy()
def onclick(self, event):
z1, r1 = event.xdata, event.ydata
print(z1, r1)
if self.first_click:
self.first_click = False
self.d1 = (z1, r1)
else:
self.first_click = True
self.d2 = (z1, r1)
distance = sqrt((((self.d1[0]) - (self.d2[0])) ** 2) + (((self.d1[1]) - (self.d2[1])) ** 2))
print("The shift between ", self.d1, "and", self.d2, "is", distance)
dp = DistancePlot()
the answer in the comment was helpful but this is not exactly what I want, I tried to use the same logic to get to my solution but it didn't work and I will share it with you.
import matplotlib.pyplot as plt
from matplotlib.widgets import Cursor
import mplcursors
import numpy as np
import tkinter as tk
#from tkinter import simpledialog
class DistancePlot:
def __init__(self):
ROOT = tk.Tk()
ROOT.withdraw()
ROOT.geometry("500x200")
# USER_INP = 1
#random sine wave
x = np.linspace(1, 10)
def f(x):
return np.sin(x) + np.random.normal(scale=0.1, size=len(x))
#fixed sine wave
time= np.arange(0, 10, 0.1)
amplitude = np.sin(time)
self.fig, self.ax = plt.subplots()
self.ax.plot(x, f(x))
self.ax.plot(time, amplitude)
self.ax.set_xlabel('X-axis')
self.ax.set_ylabel('Y-axis')
self.d1 = np.zeros(2)
self.d2 = np.zeros(2)
self.first_click = True
self.cursor = Cursor(self.ax, horizOn=True, vertOn=True, color='black', linewidth=1)
self.fig.canvas.mpl_connect('button_press_event', self.onclick)
mplcursors.cursor(hover=True)
plt.show()
def onclick(self, event):
z1, r1 = event.xdata, event.ydata
print(z1, r1)
if self.first_click:
self.first_click = False
self.d1 = np.array((z1, r1))
else:
self.first_click = True
self.d2 = np.array((z1, r1))
#distance = sqrt((((self.d1[0]) - (self.d2[0])) ** 2) + (((self.d1[1]) - (self.d2[1])) ** 2))
#print("The distance between ", self.d1, "and", self.d2, "is", distance)
delta = self.d2 - self.d1
print("The delta between ", self.d1, "and", self.d2, "is", delta)
if (abs(self.d2[0]) > abs(self.d1[0])).all():
self.ax.lines[0].set_data(self.ax.lines[0].get_data() - delta.reshape(2,1))
self.ax.relim()
self.ax.autoscale_view()
plt.draw()
else:
self.ax.lines[0].set_data(self.ax.lines[0].get_data() + delta.reshape(2,1))
self.ax.relim()
self.ax.autoscale_view()
plt.draw()
dp = DistancePlot()
what I want is use a reference graph and match it with another graph, if the graph I am adding is leading I want it to be subtracted and if it lagging I want it to move forward so adding it to the delta.
Here is an approach, moving the first curve over the given distance. Numpy arrays are used to simplify the loops. relim() and autoscale_view() recalculate the x and y limits to fit everything again inside a margin (this step can be skipped if the expected displacement is small).
import matplotlib.pyplot as plt
from matplotlib.widgets import Cursor
import mplcursors
from math import sqrt
import numpy as np
import tkinter as tk
from tkinter import simpledialog
class DistancePlot:
def __init__(self):
ROOT = tk.Tk()
ROOT.withdraw()
ROOT.geometry("500x200")
USER_INP = 2
# USER_INP = (simpledialog.askinteger(title="Plot dialig", prompt="Enter the number of the plots "))
if USER_INP is not None:
def f(x):
return np.sin(x) + np.random.normal(scale=0.1, size=len(x))
self.x = np.linspace(1, 10)
self.fig, self.ax = plt.subplots()
for i in range(USER_INP):
self.ax.plot(self.x, f(self.x))
self.ax.set_xlabel('X-axis')
self.ax.set_ylabel('Y-axis')
self.d1 = np.zeros(2)
self.d2 = np.zeros(2)
self.first_click = True
self.cursor = Cursor(self.ax, horizOn=True, vertOn=True, color='black', linewidth=1)
self.fig.canvas.mpl_connect('button_press_event', self.onclick)
mplcursors.cursor(hover=True)
plt.show()
else:
def quit(self):
self.ROOT.destroy()
def onclick(self, event):
z1, r1 = event.xdata, event.ydata
if self.first_click:
self.first_click = False
self.d1 = np.array((z1, r1))
else:
self.first_click = True
self.d2 = np.array((z1, r1))
distance = sqrt((((self.d1[0]) - (self.d2[0])) ** 2) + (((self.d1[1]) - (self.d2[1])) ** 2))
delta = self.d2 - self.d1
self.ax.lines[0].set_data(self.ax.lines[0].get_data() + delta.reshape(2,1))
self.ax.relim()
self.ax.autoscale_view()
plt.draw()
dp = DistancePlot()
If you only want to move left-right, you can use set_xdata to only change the x-positions. The following example code moves the second curve with the given displacement. If you want to move to the left, the second click should be to the left of the first.
def onclick(self, event):
z1, r1 = event.xdata, event.ydata
if self.first_click:
self.first_click = False
self.d1 = np.array((z1, r1))
else:
self.first_click = True
self.d2 = np.array((z1, r1))
delta_x = self.d1[0] - self.d2[0]
self.ax.lines[1].set_xdata(self.ax.lines[1].get_xdata() + delta_x)
self.ax.relim()
self.ax.autoscale_view()
plt.draw()

How to connect matplotlib cursor mouse_move object with slider value?

I have a figure where 2 axhlines move with mouse movement. I want to put a slider at the bottom where it will change the range of y-axis values covered by these axhlines.
enter image description here
I tried the following code. Problem is that the value of the slider changes but the mouse event object does not update.
Thanks
%matplotlib notebook
import pandas as pd
import numpy as np
import scipy.stats as stats
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from matplotlib.widgets import Slider
np.random.seed(12345)
df = pd.DataFrame([np.random.normal(32000,200000,3650),
np.random.normal(43000,100000,3650),
np.random.normal(43500,140000,3650),
np.random.normal(48000,70000,3650)],
index=[1992,1993,1994,1995])
df=df.T
data=df.describe().T
data['error']=df.sem()
data['error_range']=df.sem()*1.96
fig, ax = plt.subplots()
def plot_bar(x,y,error,title,alpha_level=0.7):
ax.bar(x,y, yerr=error,
align='center', alpha=alpha_level,
error_kw=dict(ecolor='black', elinewidth=1, capsize=5, capthick=1))
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.set_title(title)
ax.xaxis.set_major_locator(ticker.FixedLocator(data.index))
ax.yaxis.set_major_formatter(ticker.StrMethodFormatter('{x:,.0f}'))
ax.set_ylim([-5000,55000])
ax.set_xlim([1990.5,1995.5])
ax.spines['bottom'].set_position(('data',0))
ax.spines['left'].set_position(('data',1991.4))
plt.tight_layout()
return (ax, ax.get_children()[1:5])
ax, barlist=plot_bar(x=data.index,y=data['mean'],error=data['error_range'],title='Even Harder Option', alpha_level=0.6)
fig.subplots_adjust(bottom=0.1)
axcolor = 'lightgoldenrodyellow'
range_slider = plt.axes([0.2, 0.05, 0.65, 0.03], facecolor=axcolor)
slider = Slider(range_slider, 'Range', 0, 55000, valinit=10000, valstep=100)
def update(val):
slider.val = slider.val
slider.on_changed(update)
class Cursor(object):
_df=None
_bl=None
def __init__(self, ax,data_F, bars, slider):
#global slider
self._df=data_F
self._bl=bars
self.ax = ax
self.lx1 = ax.axhline(color='b')
self.lx2 = ax.axhline(color='b')
self.text1 = ax.text(1990.55, y, '%d' %45,bbox=dict(fc='white',ec='k'), fontsize='x-small')
self.text2 = ax.text(1990.55, y, '%d' %45,bbox=dict(fc='white',ec='k'), fontsize='x-small')
self._sl = slider.val
def mouse_move(self, event):
if not event.inaxes:
return
x, y = event.xdata, event.ydata
r = self._sl
y1 , y2 = y+r/2 , y-r/2
#self.lx1.set_ydata(y)
self.lx1.set_ydata(y+r/2)
self.lx2.set_ydata(y-r/2)
for i in range(4):
#shade = cmap(norm((data['mean'.values[i]-event.ydata)/df_std.values[i]))
prob1=stats.norm.cdf(y1,self._df['mean'].values[i],self._df['error'].values[i])
prob2=stats.norm.cdf(y2,self._df['mean'].values[i],self._df['error'].values[i])
shade = cmap(prob1-prob2)
self._bl[i].set_color(shade)
self.text1.set_text('%d' %y1)
self.text1.set_position((1990.55, y1))
self.text2.set_text('%d' %y2)
self.text2.set_position((1990.55, y2))
plt.draw()
cursor = Cursor(ax, data,barlist, slider)
#plt.connect('range_change', cursor.update)
plt.connect('motion_notify_event', cursor.mouse_move)

show label on hover over vertically spanned area in matplotlib

when I hover over spanned region, labels are being showed only along the sides of spanned area but not through out the area.
I want the label to be viewed in the whole area when I hover in it. How can I implement this logic?
import matplotlib.pyplot as plt
import mplcursors
plt.axvspan(2,3,gid='yes',alpha=0.3,label = 'y')
mplcursors.cursor(hover=True).connect(
"add", lambda sel: sel.annotation.set_text(sel.artist.get_label()))
plt.show()
I don't know why mplcursors does not work in the code from the question; but here is how to show an annotation upon hovering an axes span (without mplcursors):
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
span = ax.axvspan(2,3,gid='yes',alpha=0.3,label = 'y')
annot = ax.annotate("Y", xy=(0,0), xytext=(20,20), textcoords="offset points",
bbox=dict(boxstyle="round", fc="w"),
arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)
def hover(event):
vis = annot.get_visible()
if event.inaxes == ax:
cont, ind = span.contains(event)
if cont:
annot.xy = (event.xdata, event.ydata)
annot.set_visible(True)
fig.canvas.draw_idle()
else:
if vis:
annot.set_visible(False)
fig.canvas.draw_idle()
fig.canvas.mpl_connect("motion_notify_event", hover)
plt.show()

How to embed a matplotlib plot with annotation inside Gtk3 window

I trying a lot to place a matplotlib plot (that also uses annotation) to place inside gtk3 window. If there is no annotation, I can place the plot easily inside gtk3. But, I have messed up with how to do it while using annotation. I have tried this without much progress.
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from numpy import arange, pi, random, linspace
import matplotlib.cm as cm
from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas
#WINDOW to embede matplotlib
x = np.random.rand(15)
y = np.random.rand(15)
p_window = Gtk.Window()
p_window.set_default_size(750,500)
p_header = Gtk.HeaderBar()
p_window.set_titlebar(p_header)
p_header.set_subtitle("Periodic Table")
p_header.set_title("column")
p_header.set_show_close_button(True)
c = np.random.randint(1,50,size=120)
norm = plt.Normalize(1,4)
cmap = plt.cm.RdYlGn
fig,ax = plt.subplots()
sc = plt.scatter(x,y)
plt.plot(x,y)
annot = ax.annotate("", xy=(0,0), xytext=(20,20),textcoords="offset points",
bbox=dict(boxstyle="round", fc="w"),
arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)
def update_annot(ind):
pos = sc.get_offsets()[ind["ind"][0]]
annot.xy = pos
namel = "foo"
vall = "bar"
text = "{}, {}".format(namel[2:-2], vall[1:-1])
annot.set_text(text)
# annot.get_bbox_patch().set_facecolor(cmap(norm(c[ind["ind"][0]])))
annot.get_bbox_patch().set_alpha(0.4)
def hover(event):
vis = annot.get_visible()
if event.inaxes == ax:
cont, ind = sc.contains(event)
if cont:
update_annot(ind)
annot.set_visible(True)
fig.canvas.draw_idle()
else:
if vis:
annot.set_visible(False)
fig.canvas.draw_idle()
fig.canvas.mpl_connect("motion_notify_event", hover)
plt.show()
sw = Gtk.ScrolledWindow()
p_window.add(sw)
canvas = FigureCanvas(fig)
canvas.set_size_request(400,400)
sw.add_with_viewport(canvas)
p_window.show_all()
Gtk.main()
After removing pyplt
I have remove pyplt dependency as suggested, and got this:
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import numpy as np
# import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from numpy import arange, pi, random, linspace
import matplotlib.cm as cm
from matplotlib.backends.backend_gtk3cairo import FigureCanvasGTK3Cairo as FigureCanvas
#WINDOW to embede matplotlib
x = np.random.rand(15)
y = np.random.rand(15)
p_window = Gtk.Window()
p_window.set_default_size(750,500)
p_header = Gtk.HeaderBar()
p_window.set_titlebar(p_header)
p_header.set_subtitle("Periodic Table")
p_header.set_title("column")
p_header.set_show_close_button(True)
c = np.random.randint(1,50,size=120)
fig = Figure(figsize=(10,6), dpi=100)
ax = fig.add_subplot(111)
ax.set_ylabel("column")
ax.set_xlabel("Z")
sc=ax.plot(x,y, "r-o")
print(type(fig))
annot = ax.annotate("", xy=(0,0), xytext=(20,20),textcoords="offset points",
bbox=dict(boxstyle="round", fc="w"),
arrowprops=dict(arrowstyle="->"))
annot.set_visible(False)
def update_annot(ind):
pos = sc.get_offsets()[ind["ind"][0]]
annot.xy = pos
namel = "foo"
vall = "bar"
text = "{}, {}".format(namel[2:-2], vall[1:-1])
print(text)
annot.set_text(text)
# annot.get_bbox_patch().set_facecolor(cmap(norm(c[ind["ind"][0]])))
annot.get_bbox_patch().set_alpha(0.4)
def hover(event):
vis = annot.get_visible()
if event.inaxes == ax:
cont, ind = sc.contains(event)
if cont:
update_annot(ind)
annot.set_visible(True)
fig.canvas.draw_idle()
else:
if vis:
annot.set_visible(False)
fig.canvas.draw_idle()
sw = Gtk.ScrolledWindow()
p_window.add(sw)
canvas = FigureCanvas(fig)
canvas.set_size_request(400,400)
fig.canvas.mpl_connect("motion_notify_event", hover)
sw.add_with_viewport(canvas)
p_window.show_all()
Gtk.main()
which is giving me error:
python3 pop.py
Traceback (most recent call last):
File "/usr/lib64/python3.6/site-packages/matplotlib/backends/backend_gtk3.py", line 268, in motion_notify_event
FigureCanvasBase.motion_notify_event(self, x, y, guiEvent=event)
File "/usr/lib64/python3.6/site-packages/matplotlib/backend_bases.py", line 1958, in motion_notify_event
self.callbacks.process(s, event)
File "/usr/lib64/python3.6/site-packages/matplotlib/cbook.py", line 549, in process
proxy(*args, **kwargs)
File "/usr/lib64/python3.6/site-packages/matplotlib/cbook.py", line 416, in __call__
return mtd(*args, **kwargs)
File "pop.py", line 51, in hover
cont, ind = sc.contains(event)
AttributeError: 'list' object has no attribute 'contains'

Open excel file in Tkinter and plot graphs

I've just started writing Python a month ago and now getting into Tkinter. I'm trying to build a program that a user can open an excel file into Tkinter, display the dataframe and the user can choose a certain graph type, insert the variables for the X-axis and Y-axis and plot it. I've build the general layout of the GUI using PAGE but having problems on how to give commands to the widgets on displaying the dataframe and plotting the graph.
Here's my code for the GUI:
import sys
from tkinter.filedialog import askopenfilename
try:
from Tkinter import *
except ImportError:
from tkinter import *
try:
import ttk
py3 = 0
except ImportError:
import tkinter.ttk as ttk
py3 = 1
def vp_start_gui():
'''Starting point when module is the main routine.'''
global val, w, root
root = Tk()
top = New_Toplevel_1 (root)
root.mainloop()
w = None
def create_New_Toplevel_1(root, *args, **kwargs):
'''Starting point when module is imported by another program.'''
global w, w_win, rt
rt = root
w = Toplevel (root)
top = New_Toplevel_1 (w)
return (w, top)
def destroy_New_Toplevel_1():
global w
w.destroy()
w = None
class New_Toplevel_1:
def __init__(self, top=None):
'''This class configures and populates the toplevel window.
top is the toplevel containing window.'''
self._bgcolor = '#d9d9d9' # X11 color: 'gray85'
self._fgcolor = '#000000' # X11 color: 'black'
self._compcolor = '#d9d9d9' # X11 color: 'gray85'
self._ana1color = '#d9d9d9' # X11 color: 'gray85'
self._ana2color = '#d9d9d9' # X11 color: 'gray85'
top.geometry("757x1037+832+67")
top.title("New Toplevel 1")
top.configure(background="#d9d9d9")
top.configure(highlightbackground="#d9d9d9")
top.configure(highlightcolor="black")
self.Canvas1 = Canvas(top)
self.Canvas1.place(relx=0.04, rely=0.58, relheight=0.4, relwidth=0.92)
self.Canvas1.configure(background="white")
self.Canvas1.configure(borderwidth="2")
self.Canvas1.configure(highlightbackground="#d9d9d9")
self.Canvas1.configure(highlightcolor="black")
self.Canvas1.configure(insertbackground="black")
self.Canvas1.configure(relief=RIDGE)
self.Canvas1.configure(selectbackground="#c4c4c4")
self.Canvas1.configure(selectforeground="black")
self.Canvas1.configure(width=695)
self.Button2 = Button(top)
self.Button2.place(relx=0.75, rely=0.52, height=42, width=138)
self.Button2.configure(activebackground="#d9d9d9")
self.Button2.configure(activeforeground="#000000")
self.Button2.configure(background="#d9d9d9")
self.Button2.configure(disabledforeground="#a3a3a3")
self.Button2.configure(foreground="#000000")
self.Button2.configure(highlightbackground="#d9d9d9")
self.Button2.configure(highlightcolor="black")
self.Button2.configure(pady="0")
self.Button2.configure(text='''Generate Graph''')
self.Labelframe1 = LabelFrame(top)
self.Labelframe1.place(relx=0.05, rely=0.39, relheight=0.18
, relwidth=0.44)
self.Labelframe1.configure(relief=GROOVE)
self.Labelframe1.configure(foreground="black")
self.Labelframe1.configure(text='''Type of Graph''')
self.Labelframe1.configure(background="#d9d9d9")
self.Labelframe1.configure(highlightbackground="#d9d9d9")
self.Labelframe1.configure(highlightcolor="black")
self.Labelframe1.configure(width=330)
self.Radiobutton1 = Radiobutton(self.Labelframe1)
self.Radiobutton1.place(relx=0.06, rely=0.22, relheight=0.2
, relwidth=0.31)
self.Radiobutton1.configure(activebackground="#d9d9d9")
self.Radiobutton1.configure(activeforeground="#000000")
self.Radiobutton1.configure(background="#d9d9d9")
self.Radiobutton1.configure(disabledforeground="#a3a3a3")
self.Radiobutton1.configure(foreground="#000000")
self.Radiobutton1.configure(highlightbackground="#d9d9d9")
self.Radiobutton1.configure(highlightcolor="black")
self.Radiobutton1.configure(justify=LEFT)
self.Radiobutton1.configure(text='''Bar Chart''')
self.Radiobutton2 = Radiobutton(self.Labelframe1)
self.Radiobutton2.place(relx=0.06, rely=0.38, relheight=0.2
, relwidth=0.35)
self.Radiobutton2.configure(activebackground="#d9d9d9")
self.Radiobutton2.configure(activeforeground="#000000")
self.Radiobutton2.configure(background="#d9d9d9")
self.Radiobutton2.configure(disabledforeground="#a3a3a3")
self.Radiobutton2.configure(foreground="#000000")
self.Radiobutton2.configure(highlightbackground="#d9d9d9")
self.Radiobutton2.configure(highlightcolor="black")
self.Radiobutton2.configure(justify=LEFT)
self.Radiobutton2.configure(text='''Histogram''')
self.Radiobutton3 = Radiobutton(self.Labelframe1)
self.Radiobutton3.place(relx=0.06, rely=0.54, relheight=0.2
, relwidth=0.37)
self.Radiobutton3.configure(activebackground="#d9d9d9")
self.Radiobutton3.configure(activeforeground="#000000")
self.Radiobutton3.configure(background="#d9d9d9")
self.Radiobutton3.configure(disabledforeground="#a3a3a3")
self.Radiobutton3.configure(foreground="#000000")
self.Radiobutton3.configure(highlightbackground="#d9d9d9")
self.Radiobutton3.configure(highlightcolor="black")
self.Radiobutton3.configure(justify=LEFT)
self.Radiobutton3.configure(text='''Scatter Plot''')
self.Button3 = Button(top)
self.Button3.place(relx=0.28, rely=0.05, height=52, width=122)
self.Button3.configure(activebackground="#d9d9d9")
self.Button3.configure(activeforeground="#000000")
self.Button3.configure(background="#d9d9d9")
self.Button3.configure(disabledforeground="#a3a3a3")
self.Button3.configure(foreground="#000000")
self.Button3.configure(highlightbackground="#d9d9d9")
self.Button3.configure(highlightcolor="black")
self.Button3.configure(pady="0")
self.Button3.configure(text='''Browse''')
self.Button3.configure(width=122)
self.Button3.configure(command=askopenfilename)
self.Label5 = Label(top)
self.Label5.place(relx=0.03, rely=0.06, height=31, width=147)
self.Label5.configure(activebackground="#f9f9f9")
self.Label5.configure(activeforeground="black")
self.Label5.configure(background="#d9d9d9")
self.Label5.configure(disabledforeground="#a3a3a3")
self.Label5.configure(foreground="#000000")
self.Label5.configure(highlightbackground="#d9d9d9")
self.Label5.configure(highlightcolor="black")
self.Label5.configure(text='''Upload File:''')
self.Label5.configure(width=147)
self.Label3 = Label(top)
self.Label3.place(relx=0.05, rely=0.13, height=31, width=111)
self.Label3.configure(background="#d9d9d9")
self.Label3.configure(disabledforeground="#a3a3a3")
self.Label3.configure(foreground="#000000")
self.Label3.configure(text='''Data Frame :''')
self.Text1 = Text(top)
self.Text1.place(relx=0.05, rely=0.16, relheight=0.21, relwidth=0.9)
self.Text1.configure(background="white")
self.Text1.configure(font="TkTextFont")
self.Text1.configure(foreground="black")
self.Text1.configure(highlightbackground="#d9d9d9")
self.Text1.configure(highlightcolor="black")
self.Text1.configure(insertbackground="black")
self.Text1.configure(selectbackground="#c4c4c4")
self.Text1.configure(selectforeground="black")
self.Text1.configure(width=684)
self.Text1.configure(wrap=WORD)
self.Labelframe2 = LabelFrame(top)
self.Labelframe2.place(relx=0.5, rely=0.39, relheight=0.12
, relwidth=0.45)
self.Labelframe2.configure(relief=GROOVE)
self.Labelframe2.configure(foreground="black")
self.Labelframe2.configure(text='''Labelframe''')
self.Labelframe2.configure(background="#d9d9d9")
self.Labelframe2.configure(width=340)
self.Label1 = Label(self.Labelframe2)
self.Label1.place(relx=0.03, rely=0.24, height=31, width=67)
self.Label1.configure(background="#d9d9d9")
self.Label1.configure(disabledforeground="#a3a3a3")
self.Label1.configure(foreground="#000000")
self.Label1.configure(text='''X-axis :''')
self.Label2 = Label(self.Labelframe2)
self.Label2.place(relx=0.03, rely=0.56, height=31, width=66)
self.Label2.configure(background="#d9d9d9")
self.Label2.configure(disabledforeground="#a3a3a3")
self.Label2.configure(foreground="#000000")
self.Label2.configure(text='''Y-axis :''')
self.Entry1 = Entry(self.Labelframe2)
self.Entry1.place(relx=0.24, rely=0.24, relheight=0.29, relwidth=0.72)
self.Entry1.configure(background="white")
self.Entry1.configure(disabledforeground="#a3a3a3")
self.Entry1.configure(font="TkFixedFont")
self.Entry1.configure(foreground="#000000")
self.Entry1.configure(insertbackground="black")
self.Entry1.configure(width=244)
self.Entry2 = Entry(self.Labelframe2)
self.Entry2.place(relx=0.24, rely=0.56, relheight=0.29, relwidth=0.72)
self.Entry2.configure(background="white")
self.Entry2.configure(disabledforeground="#a3a3a3")
self.Entry2.configure(font="TkFixedFont")
self.Entry2.configure(foreground="#000000")
self.Entry2.configure(insertbackground="black")
self.Entry2.configure(width=244)
if __name__ == '__main__':
vp_start_gui()
I know how to save the data into a dataframe and plot graphs in Python, but i'm not sure where to write those codes when GUI is involved. All i was able to do was give a command to the 'Browse' button to search for the excel file.
self.Button3.configure(command=askopenfilename)
Can someone help me:
How to save the excel file chosen from the command into a dataframe
How to display the dataframe into the textbox below
How to plot the graph with the criteria (type of graph and axes) chosen onto the canvas at bottom
Thanks so much in advance.
In class use some self.variable to keep information and then you can use it in other methods in class.
In example I use method load() to load file and create dataframe, and method display() to display this dataframe in text widget.
try:
# Python 2
import Tkinter as tk
import ttk
from tkFileDialog import askopenfilename
except ImportError:
# Python 3
import tkinter as tk
from tkinter import ttk
from tkinter.filedialog import askopenfilename
import pandas as pd
# --- classes ---
class MyWindow:
def __init__(self, parent):
self.parent = parent
self.filename = None
self.df = None
self.text = tk.Text(self.parent)
self.text.pack()
self.button = tk.Button(self.parent, text='LOAD DATA', command=self.load)
self.button.pack()
self.button = tk.Button(self.parent, text='DISPLAY DATA', command=self.display)
self.button.pack()
def load(self):
name = askopenfilename(filetypes=[('CSV', '*.csv',), ('Excel', ('*.xls', '*.xlsx'))])
if name:
if name.endswith('.csv'):
self.df = pd.read_csv(name)
else:
self.df = pd.read_excel(name)
self.filename = name
# display directly
#self.text.insert('end', str(self.df.head()) + '\n')
def display(self):
# ask for file if not loaded yet
if self.df is None:
self.load()
# display if loaded
if self.df is not None:
self.text.insert('end', self.filename + '\n')
self.text.insert('end', str(self.df.head()) + '\n')
# --- main ---
if __name__ == '__main__':
root = tk.Tk()
top = MyWindow(root)
root.mainloop()
Here i have fetch the excel data and store it in the graph, but i want my graph should plot data after 5 second,and the graph should run in the Run time.
from openpyxl import load_workbook
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
# read from excel file
wb = load_workbook('C:\\Users\\Acer-i5-607\\Desktop\\case1.xlsx')
sheet_1 = wb.get_sheet_by_name('case1')
plt.figure(figsize=(6, 4), facecolor='Grey')
G = gridspec.GridSpec(6, 2)
axes_1 = plt.subplot(G[0, :])
x = np.zeros(sheet_1.max_row)
y = np.zeros(len(x))
for i in range(1, sheet_1.max_row):
x[i] = sheet_1.cell(row=i + 1, column=2).value
y[i] = sheet_1.cell(row=i + 1, column=4).value
#print x
#print y
# create the plot
plt.xlabel('time')
plt.ylabel('HR')
plt.plot(x, y, color='cyan', label='HR')
plt.legend(loc='upper right', fontsize='small')
plt.grid(True)
#plt.title('Reading values from an Excel file'
axes_1 = plt.subplot(G[1, :])
x = np.zeros(sheet_1.max_row)
y = np.zeros(len(x))
for i in range(1, sheet_1.max_row):
x[i] = sheet_1.cell(row=i + 1, column=2).value
y[i] = sheet_1.cell(row=i + 1, column=6).value
#print a
#print b
# create the plot
plt.xlabel('time')
plt.ylabel('Pulse')
plt.plot(x, y, color='red', label='Pulse')
plt.legend(loc='upper right', fontsize='small')
plt.grid(True)
axes_1 = plt.subplot(G[2, :])
x = np.zeros(sheet_1.max_row)
y = np.zeros(len(x))
for i in range(1, sheet_1.max_row):
x[i] = sheet_1.cell(row=i + 1, column=2).value
y[i] = sheet_1.cell(row=i + 1, column=7).value
#print x
#print y
# create the plot
plt.xlabel('time')
plt.ylabel('SpO2')
plt.plot(x, y, color='magenta', label='SpO2')
plt.legend(loc='upper right', fontsize='small')
plt.grid(True)
axes_1 = plt.subplot(G[3, :])
x = np.zeros(sheet_1.max_row)
y = np.zeros(len(x))
for i in range(1, sheet_1.max_row):
x[i] = sheet_1.cell(row=i + 1, column=2).value
y[i] = sheet_1.cell(row=i + 1, column=8).value
#print x
#print y
# create the plot
plt.xlabel('time')
plt.ylabel('Perf')
plt.plot(x, y, color='blue', label='Perf')
plt.legend(loc='upper right', fontsize='small')
plt.grid(True)
axes_1 = plt.subplot(G[4, :])
x = np.zeros(sheet_1.max_row)
y = np.zeros(len(x))
for i in range(1, sheet_1.max_row):
x[i] = sheet_1.cell(row=i + 1, column=2).value
y[i] = sheet_1.cell(row=i + 1, column=9).value
#print x
#print y
# create the plot
plt.xlabel('time')
plt.ylabel('etCO2')
plt.plot(x, y, color='yellow', label='etCO2')
plt.legend(loc='upper right', fontsize='small')
plt.grid(True)
axes_1 = plt.subplot(G[5, :])
x = np.zeros(sheet_1.max_row)
y = np.zeros(len(x))
for i in range(1, sheet_1.max_row):
x[i] = sheet_1.cell(row=i + 1, column=2).value
y[i] = sheet_1.cell(row=i + 1, column=10).value
#print x
#print y
# create the plot
plt.xlabel('time')
plt.ylabel('imCO2')
plt.plot(x, y, color='green', label='imCO2')
plt.legend(loc='upper right', fontsize='small')
plt.grid(True)
plt.xlim(0, 60000)
plt.ylim(0, 100)
plt.show()
import tkinter as tk
from tkinter import filedialog
import pandas as pd
import matplotlib.pyplot as plt
root= tk.Tk()
canvas1 = tk.Canvas(root, width = 300, height = 300, bg = 'lightsteelblue')
canvas1.pack()
def getExcel ():
global df
import_file_path = filedialog.askopenfilename()
df = pd.read_excel (import_file_path)
df["Year"] = pd.to_datetime(df["Year"], format="%Y")
ax = df.plot("Year", "Accidents",marker='o',color='r')
plt.grid()
plt.title('Yearly Graph')
ax.figure.autofmt_xdate()
plt.show()
browseButton_Excel = tk.Button(text='Import Excel File', command=getExcel, bg='green', fg='white', font=('helvetica', 12, 'bold'))
canvas1.create_window(150, 150, window=browseButton_Excel)
root.mainloop()

Resources