2017-02-28 104 views
1

这是我的第一个python项目,我试图在Matplotlib中绘制Mandelbrot集并将其放入tkinter框架中。这已经完成,但是随着GUI一起出现无关的空白图形。这个空的图有正确数量的刻度标记,而图中的绘图在绘图上有不正确数量的刻度标记(我不能确定刻度值来自哪里,但我怀疑是像素)。我现在也搜索了一段时间,如何解决这个问题无济于事。我尝试过canvas.draw,弄乱了方法和类,但我仍然无法弄清楚......以下是将运行的代码的摘录。指定显示的代码位于名为mandelbrot_image的方法中,并且MainPage类 预先感谢您。外来的Matplotlib图(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

(不涉及接受答案) 我也想知道我怎么能添加标准工具栏到情节。就像我尝试添加它,但它只显示在多余的matplotlib图中,而不是GUI中的图 – Simon

+0

还没有为您提供[答案](http://stackoverflow.com/a/42483817/4124317)解决了两个数字出现的问题?你之间有什么变化? – ImportanceOfBeingErnest

+0

您提供的答案将该图插入到tkinter画布中(我很感激)。第二个数字伴随着解决方案。 – Simon

回答

1

很显然,由于致电pyplot.xticks()而创建了一个新数字。虽然这种行为是不是在Python 2.7重复性好,我是不确定的原因吧,一个解决方案是使用axes的API命令:

为了防止进一步的并发症,它可能是明智的通过代码使用matplotlib API,完全摆脱pyplot(plt)。

Concering的导航栏,我能够使用MainPage__init__功能里面以下是获得:

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

再次感谢你 – Simon