2017-02-28 6 views
1

Dies ist mein erstes Python-Projekt und ich versuche, das Mandelbrot-Set in Matplotlib zu plazieren und es in einen Tkinter-Frame zu legen. Dies wurde bereits durchgeführt, jedoch erscheint eine überflüssige leere Zahl zusammen mit der GUI. Dieser leere Plot hat die korrekte Anzahl von Tick-Markierungen, während der Plot in der GUI die falsche Anzahl von Tick-Markierungen auf dem Plot hat (ich kann nicht herausfinden, woher die Tick-Werte kommen, aber ich vermute Pixel). Ich habe auch schon lange danach gesucht, wie ich dieses Problem vergebens lösen kann. Ich habe canvas.draw ausprobiert, mit den Methoden und Klassen rumgespielt und kann es immer noch nicht herausfinden ... Das Folgende ist ein Auszug des Codes, der ausgeführt wird. Code zur Angabe der Anzeige sind in der Methode namens mandelbrot_image und der MainPage-Klasse Vielen Dank im Voraus.Extraneous Matplotlib Abbildung (plot in tkinter)

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 numpy as np 
from numba import jit 

from 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 = 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) 




LARGE_FONT= ("Verdana", 12) 

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 = 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 
    plt.xticks(ticks, x_ticks) 
    y_ticks = ymin + (ymax-ymin)*ticks/img_width 
    plt.yticks(ticks, y_ticks) 
    ax.set_title("The Mandelbrot set") 
    norm = colors.PowerNorm(gamma) 
    ax.imshow(z.T,cmap=cmap,origin='lower',norm=norm) 


    return fig 

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) 

     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 = tk.Button(self, text="Lets Begin", 
        command=lambda: controller.show_frame(MainPage)) 
     button.pack() 
class MainPage(tk.Frame): 
    def getcheckvalue(self): 
     print (self.mvar.get()) 

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




     fig = mandelbrot_image() 
     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() 
+0

(nicht zu akzeptieren Antwort verwandt) Ich wurde auch gefragt, wie ich die Standard-Symbolleiste hinzufügen könnte zum Grundstück. Ich habe versucht, es hinzuzufügen, aber es zeigt sich nur in der fremden Matplotlib-Figur, nicht die Handlung in der GUI – Simon

+0

Hat Ihnen nicht schon [eine Antwort] (http://stackoverflow.com/a/42483817/4124317) was löste das Problem, dass zwei Figuren erscheinen? Was hast du zwischendurch gewechselt? – ImportanceOfBeingErnest

+0

Die Antwort, die du zur Verfügung gestellt hast, hat die Handlung in die tkinter Leinwand eingefügt (für die ich dankbar bin). Die zweite Figur begleitete die Lösung. – Simon

Antwort

1

So offenbar eine neue Figur ist wegen eines Aufrufs pyplot.xticks() erstellt. Während dieses Verhalten in Python 2.7 nicht reproduzierbar ist und ich bin unsicher über die Gründe für sich, ist eine Lösung, die die API-Befehle der axes zu verwenden:

Um weitere Komplikationen zu vermeiden, kann es sinnvoll sein, Verwenden Sie die Matplotlib API über den Code, pyplot (plt) vollständig loszuwerden.

die Navigationsleiste concering, konnte ich es mit dem folgenden innerhalb der MainPage ‚s __init__ Funktion erhalten:

fig = mandelbrot_image() 
    canvas = FigureCanvasTkAgg(fig, self) 
    canvas.show() 
    toolbar = NavigationToolbar2TkAgg(canvas, self) 
    toolbar.update() 
    canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True) 
+0

Vielen Dank noch einmal – Simon