To display shapefile in tkinter? - python-3.x

I want the "shapefile" mentioned below in the code to be displayed inside the "sideFrame" of the tkinter window. But now, the shapefile is getting opened up in the another window which I don't want to. That is, I want to display the "shapefile" inside the right frame of the "tkinter" window.I am new to this field, so could be clear with the explanation along with the code.
import matplotlib
import matplotlib.pyplot as plt
matplotlib.use("TkAgg") # for backend
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
def forSubmit():
if MyVar1.get()== 0 or MyVar2.get()==0:
messagebox.showwarning("Warning", "Select input files!")
fp = r"F:\ISRO\Spatial_Data\grid_jagalur_spatialjoin.shp"
data = gpd.read_file(fp)
print (type(data))
data.head()
data.plot()
plt.show(sideFrame)
middleFrame = LabelFrame(root,width=800,text="Input data")
middleFrame.grid(row=1, column=0, padx=8, pady=8, sticky=N+S+W+E)
middleFrame.grid_rowconfigure(0, weight=1)
middleFrame.grid_rowconfigure(1, weight=0)
middleFrame.grid_columnconfigure(0, weight=1)
middleFrame.grid_columnconfigure(1, weight=1)
Button6 = Button(middleFrame, text="View", command=forSubmit)
Button6.grid(row=1, column=1, padx=4, pady=4,sticky=E)
sideFrame = LabelFrame(root,width=500, bg="powder blue", text="Image")
sideFrame.grid(row=0, column=1, padx=8, pady=8, sticky=N+S+W+E, rowspan=3)
sideFrame.grid_rowconfigure(0, weight=1)
sideFrame.grid_rowconfigure(1, weight=1)
sideFrame.grid_rowconfigure(2, weight=1)
sideFrame.grid_columnconfigure(0, weight=1)
sideFrame.grid_columnconfigure(1, weight=1)

You should add a FigureCanvasTkAgg widget to your sideFrame and then try something on the following lines:
fig, ax = plt.subplots(nrows = 1, ncols = 1)
cavnas_plot = FigureCanvasTkAgg(fig, master = sideFrame)
canvas_plot.draw()
canvas_plot.get_tk_widget.grid(row = 0, column = 0)
Ensure that there is enough space for the sideFrame to be visible on the main window

Related

Why my ttk style won't apply to my Frame?

I've been fighting with ttk style for about 2 days right now, but nothing seems to work. I've tried a lot of different approaches, but I had no effect. Right now, I just want to see that the Frame that I'm trying to add to my App is working, could you please show me where is the problem?
import tkinter as tk
from tkinter import ttk
class App(tk.Tk):
def __init__(self):
super().__init__()
# Main window configuration
self.title("Work Tracker")
self.geometry("600x700")
self.resizable(0,0)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
# Styles
style = ttk.Style()
style.configure('TFrame', background='blue')
# Logo frame
frame = ttk.Frame(self, width=200, height=150)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
frame.grid_propagate(False)
frame.grid(row=0, column=0, sticky='nw')
label = ttk.Label(frame, text ="WORK TRACKER")
label.pack()
def main():
app = App()
app.mainloop()
main()

How can I fix my button positions on python tkinter?

I want to fix the position of my two buttons like if I resize my window the buttons will remain in their positions. Or My buttons dynamically resize with the window size. I have positioned my buttons using place. But I ain't getting success. Here's the code so far.
import turtle
import tkinter as tk
##wn=turtle.Screen()
wn=tk.Tk()
image=tk.PhotoImage(file="MS-3.PNG")
wn.geometry("700x700")
label1=tk.Label(wn,image=image)
label1.pack(side="top",fill="both",expand="yes")
label1.grid_rowconfigure(0, weight=1)
label1.grid_columnconfigure(0, weight=1)
label1.grid_rowconfigure(1, weight=1)
def callback1():
import Detection1
def callback():
import detection
button1=tk.Button(label1,text="Health Identification", command=callback, bd=12,bg="grey",font="caliber")
button1.place(x=100,y=500 )
label1.image=image
button2=tk.Button(label1,text="Disease Classification", command=callback1, bd=10,bg="grey",font="caliber")
button2.place(x=400, y=500 )
label1.image=image
wn.mainloop()
Sadia: If I understood your question correctly, you could make your windows non-resizable with wn.resizable(False, False). Then place your buttons exactly where you want them to be. If you are new to tkinter and python, making every object resizable might be a bit too complex to begin with.
Hopefully this helps.
import turtle
import tkinter as tk
from PIL import Image, ImageTk
##wn=turtle.Screen()
wn = tk.Tk()
wn.geometry("700x700")
wn.resizable(False, False)
img = ImageTk.PhotoImage(Image.open("MS-3.PNG"))
label1 = tk.Label(wn, image=img)
label1.pack(side="top", fill="both", expand="yes")
# label1.grid_rowconfigure(0, weight=1)
# label1.grid_columnconfigure(0, weight=1)
# label1.grid_rowconfigure(1, weight=1)
def callback1():
import Detection1
def callback():
import detection
button1 = tk.Button(label1, text="Health Identification", command=callback, bd=12, bg="grey", font="caliber")
button1.place(x=100, y=500)
button2 = tk.Button(label1, text="Disease Classification", command=callback1, bd=10, bg="grey", font="caliber")
button2.place(x=400, y=500)
wn.mainloop()

Tkinter Grid Geometry Resizing issue

Browse Button in Right Hand side Panel is being separated when resizing the window. I want the whole thing to stay together and resizing equally.
import tkinter as tk
from tkinter import ttk
from tkinter import *
class AppLayout(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.masterPane = tk.PanedWindow(self )
self.leftPane = tk.Frame(self.masterPane,relief = 'raised',bg='black',width =100)
self.masterPane.add(self.leftPane)
self.rightPane = tk.Frame(self.masterPane)
self.masterPane.add(self.rightPane)
self.masterPane.pack(fill = 'both',expand = True)
name_entry = tk.Entry(self.rightPane,font =('calibre',10,'normal'))
Browse_Button = tk.Button(self.rightPane,text = 'Browse')
Upload_Button = tk.Button(self.rightPane,text = 'Upload')
name_entry.grid(row=1,column=1)
Browse_Button.grid(row=1,column=2)
Upload_Button.grid(row=1,column=1,pady =(50,0))
self.rightPane.columnconfigure(1, weight=1)
self.rightPane.rowconfigure(1, weight=1)
app = AppLayout()
app.mainloop()
There are four things you need to change:
don't double-import tkinter. It's enough to import * from it.
configure the second column of the rightPane to extend when you resize the window.
Put the button at the western side (W) of the second column by adding sticky=W to the .grid() method.
Glue the Entry widget to the Eastern and Western side of column 1. So, it will get wider when this column extends.
With the following code, it works.
You can also use the .colmnconfigure() and .rowconfigure() method on frame widgets to specify how the other pane extends and how the app resizes vertically.
from tkinter import ttk
from tkinter import *
class AppLayout(Tk):
def __init__(self):
Tk.__init__(self)
self.masterPane = PanedWindow(self )
self.leftPane = Frame(self.masterPane,relief = 'raised',bg='black',width =100)
self.masterPane.add(self.leftPane)
self.rightPane = Frame(self.masterPane)
self.rightPane.columnconfigure(2, weight=1)
self.masterPane.add(self.rightPane)
self.masterPane.pack(fill = 'both',expand = True)
name_entry = Entry(self.rightPane,font =('calibre',10,'normal'))
Browse_Button = Button(self.rightPane,text = 'Browse')
Upload_Button = Button(self.rightPane,text = 'Upload')
name_entry.grid(row=1,column=1,sticky=W+E)
Browse_Button.grid(row=1,column=2, sticky=W)
Upload_Button.grid(row=1,column=1,pady =(50,0))
self.rightPane.columnconfigure(1, weight=1)
self.rightPane.rowconfigure(1, weight=1)
app = AppLayout()
app.mainloop()

How to update matplotlib embedded into tkinter?

The problem is that I want to draw a plot by clicking on a button but it doesn't work. However, when I call draw from __init__, the plot appears on the screen.
Plotter.py
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
class Plotter(FigureCanvasTkAgg):
def __init__(self, master):
self.figure = Figure(dpi=100)
super().__init__(self.figure, master=master)
self.axes = self.figure.add_subplot(111)
self.get_tk_widget().grid(column=0, row=0, sticky='nsew')
def draw(self):
self.axes.clear()
x_list = [x for x in range(0, 100)]
y_list = [x^3 for x in x_list]
self.axes.plot(x_list, y_list, color='y')
MainApplication.py
from tkinter import ttk
import tkinter as tk
import plotter
class MainApplication(ttk.Frame):
def __init__(self, master, *args, **kwargs):
super().__init__(root)
self.grid(column=0, row=0, sticky='nsew')
frame = ttk.Frame(self, borderwidth=8)
frame.grid(column=0, row=0, sticky='nsew')
frame.rowconfigure(0, weight=1)
notes = ttk.Notebook(frame)
notes.grid(column=0, row=0, sticky='nsew')
notes.rowconfigure(0, weight=1)
page = ttk.Frame(notes)
notes.add(page, text='Picture')
plot = plotter.Plotter(page)
# plot.draw() # This call updates the plot
input_frame = ttk.Frame(self)
input_frame.grid(column=1, row=0, sticky='nsew')
# this binding doesn't update the plot
button = ttk.Button(input_frame, text='Plot', \
command=lambda: plot.draw())
button.grid(column=0, row=4, columnspan=2, sticky='ew')
root = tk.Tk()
MainApplication(root)
root.mainloop()
Personally I would write this up in a single class so that we can use class attributes and methods to control everything with ease. Also you do not need a lambda here. Just save the reference to the command button and not a lambda call. That said you were also overwriting the draw method of FigureCanvasTkAgg so change the draw() method to something else.
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from tkinter import ttk
import tkinter as tk
class MainApplication(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
notes = ttk.Notebook(self)
notes.grid(column=0, row=0, sticky='nsew')
notes.rowconfigure(0, weight=1)
self.page = ttk.Frame(notes)
notes.add(self.page, text='Picture')
self.plotter()
input_frame = ttk.Frame(self)
input_frame.grid(column=1, row=0, sticky='nsew')
button = ttk.Button(input_frame, text='Plot', command=self.new_draw)
button.grid(column=0, row=4, columnspan=2, sticky='ew')
def plotter(self):
self.figure = Figure(dpi=100)
self.plot_canvas = FigureCanvasTkAgg(self.figure, self.page)
self.axes = self.figure.add_subplot(111)
self.plot_canvas.get_tk_widget().grid(column=0, row=0, sticky='nsew')
def new_draw(self):
self.axes.clear()
x_list = [x for x in range(0, 100)]
y_list = [x^3 for x in x_list]
self.axes.plot(x_list, y_list, color='y')
self.plot_canvas.draw_idle()
MainApplication().mainloop()
You overwrote the canvas' draw method without reimplementing it. But since you do not want to update your plot on every draw-event anyways, I'd suggest to call the method to update the plot differently, e.g. draw_lists. Inside draw_lists you would then need to call the draw method of the canvas (or in this case better draw_idle).
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
class Plotter(FigureCanvasTkAgg):
def __init__(self, master):
self.figure = Figure(dpi=100)
super().__init__(self.figure, master=master)
self.axes = self.figure.add_subplot(111)
self.get_tk_widget().grid(column=0, row=0, sticky='nsew')
def draw_lists(self):
self.axes.clear()
x_list = [x for x in range(0, 100)]
y_list = [x^3 for x in x_list]
self.axes.plot(x_list, y_list, color='y')
self.draw_idle()
from tkinter import ttk
import tkinter as tk
class MainApplication(ttk.Frame):
def __init__(self, master, *args, **kwargs):
super().__init__(root)
self.grid(column=0, row=0, sticky='nsew')
frame = ttk.Frame(self, borderwidth=8)
frame.grid(column=0, row=0, sticky='nsew')
frame.rowconfigure(0, weight=1)
notes = ttk.Notebook(frame)
notes.grid(column=0, row=0, sticky='nsew')
notes.rowconfigure(0, weight=1)
page = ttk.Frame(notes)
notes.add(page, text='Picture')
plot = Plotter(page)
input_frame = ttk.Frame(self)
input_frame.grid(column=1, row=0, sticky='nsew')
# this binding doesn't update the plot
button = ttk.Button(input_frame, text='Plot', \
command=lambda: plot.draw_lists())
button.grid(column=0, row=4, columnspan=2, sticky='ew')
root = tk.Tk()
MainApplication(root)
root.mainloop()

python - calling plt.figure prevents Checkbutton from update - Tkinter

A GUI that works with different pages, one is a graph page using the animate function, and a second page should start a guide, the guide will depend on what you click in a checkbutton. I have created a post because I thought I was the checkbutton that was not well defined, but now i found that calling the f=plt.figure() is prevent the upgrade of the checkbutton.
See this code works for the Checkbutton: - Before the animate function .. But then the graphic update on the other page does not work since f is not defined in the animate function. If i put the animate function and f definition in the PageThree (GRAPHIC page) the update of the figure fails.
But when i allow the f=plt.figure() , graphic is fine, but checkbutton stays False all the time...
import matplotlib
from tkinter import *
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
import tkinter as tk
from tkinter import ttk
import numpy as np
import matplotlib.animation as animation
from matplotlib import style
from matplotlib import pyplot as plt
from scipy.misc import *
import pandas as pd
import webbrowser
import subprocess
import csv
import matplotlib.ticker as mticker
import matplotlib.dates as mdates
from os import startfile
from time import time
LARGE_FONT = ("Times", 11, "bold italic")
NORM_FONT = ("Helvetica", 9)
SMALL_FONT = ("Helvetica",7)
HELP_FONT=("Times", 9 , "bold")
pullDataMS=pd.read_table("test.raw.spectrum_table.tsv", header=1)
LevelMS=pullDataMS.groupby('msLevel')
rt=pullDataMS['rt']
TIC=pullDataMS['TIC']
MS1=LevelMS.get_group('ms1')
MS2=LevelMS.get_group('ms2')
### THIS CALL overplots the update? -.- ###
#f = plt.figure(facecolor="white")**
######################
def animate (i):
pullData=pd.read_table("InstrumentPerformance.txt", parse_dates=True,
dayfirst=True, index_col=1)
Names_In = ['Q1','Q2','Q3']
Inst=pullData.groupby('Instrument')
a = f.add_subplot(2,3,1)
a2 = f.add_subplot(2,3,2, sharex=a)
a3=f.add_subplot(2,3,3)
a4=f.add_subplot(2,3,4)
a5=f.add_subplot(2,3,5)
a7=f.add_subplot(2,6,11)
f.subplots_adjust(wspace=0.29)
a.clear()
a2.clear()
a3.clear()
a4.clear()
a5.clear()
a7.clear()
for Name in Names_In:
Q=Inst.get_group(Name)
y=Q['MS/MS recorded']
x=Q['Identified peptides']
a.plot(x, "o",label='['+Name+"]")
a.plot(x, 'k-', lw=0.7, label='_nolegend_')
a2.plot(y, 'o',label='['+Name+']')
a2.plot(y, 'k-', label='_nolegend_', lw=0.7)
a.xaxis.set_major_locator(mticker.MaxNLocator(5))
a.xaxis.set_major_formatter(mdates.DateFormatter("%d-%m-%Y"))
a.set_ylabel('# of unique peptide sequences')
a2.set_ylabel('# of MS/MS spectra')
a.legend(loc='upper left',fancybox=True, numpoints=1, shadow=True,prop={'size':9})
a2.legend(loc='upper left',fancybox=True, numpoints=1, shadow=True,prop={'size':9})
a.set_xlim(np.array([-20,20])+a.get_xlim())
a.set_ylim(np.array([0,2000])+a.get_ylim())
a2.set_xlim(np.array([-20,20])+a.get_xlim())
a2.set_ylim(np.array([0,5000])+a.get_ylim())
class PAL3_guide(tk.Tk):
def __init__(self,*args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand = True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (StartPage,Tut01,PageThree):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(StartPage)
def show_frame(self, cont):
frame=self.frames[cont]
frame.tkraise()
class StartPage(tk.Frame):
def __init__(self,parent, controller):
tk.Frame.__init__(self,parent, background="white")
button_PAL = ttk.Button(self, text="Setup Guide", command=lambda:controller.show_frame(Tut01))
button_PAL.pack()
button2 = ttk.Button(self, text="Graph Page 1",
command=lambda: controller.show_frame(PageThree))
button2.pack()
class Tut01(tk.Frame):
def __init__(self,parent,controller):
tk.Frame.__init__(self,parent)
self.parent=parent
self.initUI()
def initUI(self):
self.var=BooleanVar()
cb=Checkbutton(self,text="show", variable=self.var, command=self.onClick)
cb.select()
cb.place(x=50,y=50)
def onClick(self):
if self.var.get()== True:
print("hi")
else:
print("buh")
class PageThree(tk.Frame):
def __init__(self,parent,controller):
tk.Frame.__init__(self,parent)
label = tk.Label(self, text="GraphPage", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = ttk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
button1.pack()
canvas = FigureCanvasTkAgg(f, self)
canvas.show()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
toolbar=NavigationToolbar2TkAgg(canvas,self)
toolbar.update()
canvas._tkcanvas.pack(side=tk.TOP,fill=tk.BOTH, expand=True)
app = PAL3_guide()
app.geometry("1280x920")
ani = animation.FuncAnimation(f, animate, interval=10000)
app.mainloop()
EDIT FOR MIXONE: yes i have tried to do something like :
def animate (f):
pullData=pd.read_table("InstrumentPerformance.txt", parse_dates=True,
dayfirst=True, index_col=1)
Names_In = ['Q1','Q2','Q3']
Inst=pullData.groupby('Instrument')
a = f.add_subplot(2,3,1)
a2 = f.add_subplot(2,3,2, sharex=a)...
...
and:
class PageThree(tk.Frame):
def __init__(self,parent,controller):
tk.Frame.__init__(self,parent)
label = tk.Label(self, text="GraphPage", font=LARGE_FONT)
label.pack(pady=10, padx=10)
button1 = ttk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
button1.pack()
f=plt.figure()
ani = animation.FuncAnimation(f, animate(f), interval=10000)
canvas = FigureCanvasTkAgg(f, self)
canvas.show()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)
#toolbar=NavigationToolbar2TkAgg(canvas,self)
#toolbar.update()
#canvas._tkcanvas.pack(side=tk.TOP,fill=tk.BOTH, expand=True)
app = PAL3_guide()
app.geometry("1280x920")
app.mainloop()
In this case the Checkbutton works, but the figure is not updated but it is plotted in the beginning.

Resources