1
我再次需要幫助... 我對python非常陌生,我試圖在GUI中繪製Mandelbrot集。目前我正在研究一個函數,在該函數中我可以更改分形的渲染顏色。問題是我無法弄清楚如何用新的替換舊的繪圖。一切都需要重新繪製陰謀才行(終端甚至暫停,好像它正在重新計算,但不會產生任何東西)。我曾嘗試在互聯網上提出的所有不同的地方插入fig.clf(),但我仍然無法弄清楚。附件是代碼將運行的摘錄。此代碼的特定位置位於名爲mandelbrot_image和類MainPage的函數中。先謝謝你。用戶輸入更新Matplotlib圖
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import tkinter as tk
from tkinter import ttk
from tkinter import *
#import tkinter.messagebox
from tkinter import messagebox
import numpy as np
from numba import jit
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 = z
for n in range(maxiter):
az = abs(z)
if az > horizon:
return n - np.log(np.log(az))/np.log(2) + log_horizon
z = z*z + c
return 0
@jit
def mandelbrot_set(xmin,xmax,ymin,ymax,width,height,maxiter):
horizon = 2.0 ** 40
log_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='hot',gamma=0.3): #the coords and cmap are essentially a filler for the imput in the plot() function at the bottom of the code
dpi = 80
img_width = dpi * width
img_height = dpi * height
x,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_width
ax.set_xticks(ticks); ax.set_xticklabels(x_ticks)
y_ticks = ymin + (ymax-ymin)*ticks/img_width
ax.set_yticks(ticks); ax.set_yticklabels(y_ticks)
ax.set_title("The Mandelbrot set")
norm = colors.PowerNorm(gamma)
#fig.clf()
ax.imshow(z.T,cmap=cmap,origin='lower',norm=norm)
return fig
LARGE_FONT= ("Verdana", 12)
NORM_FONT= ("Verdana", 10)
class base(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
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)
self.frames = {}
for F in (StartPage, MainPage):
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)
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 MainPage(tk.Frame):
def var_states(self): #this is supposed to send code to run plot() again but it doesnt do it
print (self.combobox.get())
print (self.colr)
self.plot()
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)
values = ['jet', 'rainbow', 'ocean', 'hot', 'cubehelix','gnuplot','terrain','prism', 'pink']
button1 = ttk.Button(self, text="Back to Home",
command=lambda: controller.show_frame(StartPage))
button1.pack()
button2 = ttk.Button(self, text="Re-Render",
command=self.plot)
button2.pack()
self.mvar = IntVar()
self.cbutton = ttk.Checkbutton(self, text="shadow",onvalue=0, offvalue=1, variable=self.mvar)
self.cbutton.pack()
self.combobox = ttk.Combobox(self, values=values)
self.combobox.current(0)
self.combobox.pack(side = RIGHT)
global colr
self.colr = self.combobox.get()
self.plot()
def plot (self):
colr = self.combobox.get()
print (colr)
#fig.clf() this does nothing and crashes
fig = mandelbrot_image(-0.8,-0.7,0,0.1,cmap=colr) #this is calling the method with the coordinates of the plot and the color scheme
#fig.clf()this works but just leaves the screen completely blank
canvas = FigureCanvasTkAgg(fig, self)
#fig.clf()this works but just leaves the screen completely blank
canvas.show()
#canvas.clf()
#fig.clf() this works but just leaves the screen completely blank
canvas.get_tk_widget().pack(side = BOTTOM, fill=tk.BOTH, expand=True)
toolbar = NavigationToolbar2TkAgg(canvas, self)
toolbar.update()
canvas._tkcanvas.pack(side = BOTTOM, fill=tk.BOTH, expand=True)
app = base()
app.geometry ("800x600")
app.mainloop()
你是上帝。感謝您再次幫助我,我誠實地仍然會被一個沒有您的幾個按鈕的tkinter窗口卡住。有了這個幫助,我應該可以完成一些我需要添加的東西,然後完成這個程序(我將把它放在我的github上,以及我未來的python項目,現在可以感謝你了)你的幫助肯定有幫助幫助我在matplotlib,tkinter和Python中獲得更好的理解。我不能要求更好的資產/導師。 (感謝您直接寫這段代碼) – Simon
您可以通過[upvoting](http://meta.stackexchange.com/questions/173399/how-to-upvote-on-stack-overflow)來顯示您的感謝問題和在嘗試解決問題時對您有用的答案,當然包括您自己的問題的答案。請注意,SO不是一種代碼編寫服務,您不能總是找到有時間回答這些問題的人。對於未來,我建議(重新)閱讀[問]以及如何提供[mcve]。創建這樣的最小示例還將幫助您自己找到解決方案。 – ImportanceOfBeingErnest
謝謝,下次我會問我會縮短我的代碼。我也提出了你的答案,但是因爲我有不到15的聲望,他們沒有公開展示(然而他們應該被記錄下來)。 – Simon