Matplotlib functions in tkinter

2024/10/15 7:31:09

This is my first python project so I understand that this problem may seem a bit stupid.
I am trying to create a Mandelbrot renderer. I am piecing code together from tutorials and code that I understand to make something.
So basically I have all the maths and the basic functions of the GUI for the renderer but I can't get the matplotlib graph to actually graph inside the tkinter GUI.
The matplolib display part is actually a function that needs mandelbrot_image(-0.8,-0.7,0,0.1,cmap='hot') to run. If that code is introduced, the Mandelbrot set is plotted, but in a different matplotlib window.

Here is all my code, I thank you in advance and once again I apologize.

   #big thanks and credit goes to to Jean Puget from IBM, SentDex from pythonprogramming.net, and stackoverflow #for teaching me how to use python and inspiring much of this following codeimport matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg,    NavigationToolbar2TkAgg
from matplotlib.figure import Figureimport tkinter as tk
from tkinter import ttkimport numpy as np
from numba import jitfrom matplotlib import pyplot as plt
from matplotlib import colors#maths and display code derived/inspired from Jean Francois Puget 
#https://www.ibm.com/developerworks/community/blogs/jfp/entry/My_Christmas_Gift?lang=en
@jit
def mandelbrot(z,maxiter,horizon,log_horizon):c = zfor n in range(maxiter):az = abs(z)if az > horizon:return n - np.log(np.log(az))/np.log(2) + log_horizonz = z*z + creturn 0@jitdef mandelbrot_set(xmin,xmax,ymin,ymax,width,height,maxiter):horizon = 2.0 ** 40log_horizon = np.log(np.log(horizon))/np.log(2)r1 = np.linspace(xmin, xmax, width)r2 = np.linspace(ymin, ymax, height)n3 = np.empty((width,height))for i in range(width):for j in range(height):n3[i,j] = mandelbrot(r1[i] + 1j*r2[j],maxiter,horizon, log_horizon)return (r1,r2,n3)#Display setup
fig = Figure()
ax = fig.add_subplot(111)
xmin = -2.0
xmax = 0.5
ymin = -1.25
ymax = 1.25
cmap='hot'
# width=20
# height=20
# maxiter=1000
# gamma=0.3def mandelbrot_image(xmin,xmax,ymin,ymax,width=10,height=10,\maxiter=1000,cmap='jet',gamma=0.3):dpi = 80img_width = dpi * widthimg_height = dpi * heightx,y,z = mandelbrot_set(xmin,xmax,ymin,ymax,img_width,img_height,maxiter)fig, ax = plt.subplots(figsize=(width, height),dpi=72)ticks = np.arange(0,img_width,3*dpi)x_ticks = xmin + (xmax-xmin)*ticks/img_widthplt.xticks(ticks, x_ticks)y_ticks = ymin + (ymax-ymin)*ticks/img_widthplt.yticks(ticks, y_ticks)ax.set_title(cmap)norm = colors.PowerNorm(gamma)ax.figshow(z.T,cmap=cmap,origin='lower',norm=norm)LARGE_FONT= ("Verdana", 12)class base(tk.Tk):def __init__(self, *args, **kwargs):tk.Tk.__init__(self, *args, **kwargs)tk.Tk.iconbitmap(self, "iconz.ico")tk.Tk.wm_title(self, "Mandelbrot Renderer")container = tk.Frame(self)container.pack(side="top", fill="both", expand = True)container.grid_rowconfigure(0, weight=1)container.grid_columnconfigure(0, weight=1)menubar = tk.Menu(container)filemenu = tk.Menu(menubar, tearoff=0)filemenu.add_separator()filemenu.add_command(label="Exit", command=quit)menubar.add_cascade(label="File", menu=filemenu)self.frames = {}for F in (StartPage, MainPage, Donate):frame = F(container, self)self.frames[F] = frameframe.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)label = tk.Label(self, text="Start Page", font=LARGE_FONT)label.pack(pady=10,padx=10)button = ttk.Button(self, text="Lets Begin",command=lambda: controller.show_frame(MainPage))button.pack()class Donate(tk.Frame):def __init__(self, parent, controller):tk.Frame.__init__(self, parent)label = tk.Label(self, text="Donate", font=LARGE_FONT)label.pack(pady=10,padx=10)button1 = ttk.Button(self, text="Back",command=lambda: controller.show_frame(MainPage))button1.pack()class MainPage(tk.Frame):def __init__(self, parent, controller):tk.Frame.__init__(self, parent)label = tk.Label(self, text="Graph Page!", 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()button2 = ttk.Button(self, text="Donate",command=lambda: controller.show_frame(Donate))button2.pack()canvas = FigureCanvasTkAgg(fig, self)canvas.show()canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)toolbar = NavigationToolbar2TkAgg(canvas, self)toolbar.update()canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)  app = base()
app.geometry ("800x600")
app.mainloop()
Answer

The main problem here is that you create two different figures. The one that lives in the Tk frame is not the one you plot the mandelbrot image to.
So you need to work with the same figure throughout the code.
One option is to let the mandelbrot_image create the figure and return it to later be able to supply it to the FigureCanvas. See below for a complete solution.

An additional problem is that matplotlib does not have a figshow method. You probably want imshow()instead.

import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figureimport Tkinter as tkimport numpy as np
from numba import jitfrom matplotlib import pyplot as plt
from matplotlib import colors#maths and display code derived/inspired from Jean Francois Puget 
#https://www.ibm.com/developerworks/community/blogs/jfp/entry/My_Christmas_Gift?lang=en
@jit
def mandelbrot(z,maxiter,horizon,log_horizon):c = zfor n in range(maxiter):az = abs(z)if az > horizon:return n - np.log(np.log(az))/np.log(2) + log_horizonz = z*z + creturn 0@jit
def mandelbrot_set(xmin,xmax,ymin,ymax,width,height,maxiter):horizon = 2.0 ** 40log_horizon = np.log(np.log(horizon))/np.log(2)r1 = np.linspace(xmin, xmax, width)r2 = np.linspace(ymin, ymax, height)n3 = np.empty((width,height))for i in range(width):for j in range(height):n3[i,j] = mandelbrot(r1[i] + 1j*r2[j],maxiter,horizon, log_horizon)return (r1,r2,n3)def mandelbrot_image(xmin=-2.,xmax=0.5,ymin=-1.25,ymax=1.25,width=10,height=10,\maxiter=1000,cmap='jet',gamma=0.3):dpi = 80img_width = dpi * widthimg_height = dpi * heightx,y,z = mandelbrot_set(xmin,xmax,ymin,ymax,img_width,img_height,maxiter)fig = Figure(figsize=(width, height))ax = fig.add_subplot(111)ticks = np.arange(0,img_width,3*dpi)x_ticks = xmin + (xmax-xmin)*ticks/img_widthplt.xticks(ticks, x_ticks)y_ticks = ymin + (ymax-ymin)*ticks/img_widthplt.yticks(ticks, y_ticks)ax.set_title(cmap)norm = colors.PowerNorm(gamma)ax.imshow(z.T,cmap=cmap,origin='lower',norm=norm)return figLARGE_FONT= ("Verdana", 12)class base(tk.Tk):def __init__(self, *args, **kwargs):tk.Tk.__init__(self, *args, **kwargs)#tk.Tk.iconbitmap(self, "iconz.ico")tk.Tk.wm_title(self, "Mandelbrot Renderer")container = tk.Frame(self)container.pack(side="top", fill="both", expand = True)container.grid_rowconfigure(0, weight=1)container.grid_columnconfigure(0, weight=1)menubar = tk.Menu(container)filemenu = tk.Menu(menubar, tearoff=0)filemenu.add_separator()filemenu.add_command(label="Exit", command=quit)menubar.add_cascade(label="File", menu=filemenu)self.frames = {}for F in (StartPage, MainPage):frame = F(container, self)self.frames[F] = frameframe.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)label = tk.Label(self, text="Start Page", font=LARGE_FONT)label.pack(pady=10,padx=10)button = tk.Button(self, text="Lets Begin",command=lambda: controller.show_frame(MainPage))button.pack()class MainPage(tk.Frame):def __init__(self, parent, controller):tk.Frame.__init__(self, parent)label = tk.Label(self, text="Graph Page!", font=LARGE_FONT)label.pack(pady=10,padx=10)button1 = tk.Button(self, text="Back to Home",command=lambda: controller.show_frame(StartPage))button1.pack()# create a figure with the mandelbrot plot insidefig = mandelbrot_image()# attach this figure to the TK canvascanvas = FigureCanvasTkAgg(fig, self)canvas.show()canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)toolbar = NavigationToolbar2TkAgg(canvas, self)toolbar.update()canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)  app = base()
app.geometry ("800x600")
app.mainloop()

Note: In newer versions of matplotlib you should use NavigationToolbar2Tk instead of NavigationToolbar2TkAgg.

https://en.xdnf.cn/q/117858.html

Related Q&A

sudo su user -c with arguments not working

I am trying to execute command from python as another "user" with:command = "sudo su user -c player --standard=1 -o 2" subprocess.Popen(command.split(), shell=False, stdin=None, std…

Grouping data on column value

Hi I have data (in excel and text file as well) like C1 C2 C31 p a1 q b2 r c2 s dAnd I want the output like:C1 C2 C31 p,q a,b2 r,s c,dHow can I group the data…

Memory Error Python Processing Large File Line by Line

I am trying to concatenate model output files, the model run was broken up in 5 and each output corresponds to one of those partial run, due to the way the software outputs to file it start relabelling…

python assign literal value of a dictionary to key of another dictionary

I am trying to form a web payload for a particular request body but unable to get it right. What I need is to pass my body data as below data={file-data:{"key1": "3","key2&quo…

python regex findall span

I wanna find all thing between <span class=""> and </span> p = re.compile(<span class=\"\">(.*?)\</span>, re.IGNORECASE) text = re.findall(p, z)for exampl…

Why cant I view updates to a label while making an HTTP request in Python

I have this code :def on_btn_login_clicked(self, widget):email = self.log_email.get_text()passw = self.log_pass.get_text()self.lbl_status.set_text("Connecting ...")params = urllib.urlencode({…

plotting multiple graph from a csv file and output to a single pdf/svg

I have some csv data in the following format.Ln Dr Tag Lab 0:01 0:02 0:03 0:04 0:05 0:06 0:07 0:08 0:09 L0 St vT 4R 0 0 0 0 0 0…

parallel python: just run function n times [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.Want to improve this question? Update the question so it focuses on one problem only by editing this post.Closed 9…

how to specify the partition for mapPartition in spark

What I would like to do is compute each list separately so for example if I have 5 list ([1,2,3,4,5,6],[2,3,4,5,6],[3,4,5,6],[4,5,6],[5,6]) and I would like to get the 5 lists without the 6 I would do …

Keeping just the hh:mm:ss from a time delta

I have a column of timedeltas which have the attributes listed here. I want the output in my pandas table to go from:1 day, 13:54:03.0456to:13:54:03How can I drop the date from this output?