2017-02-27 5 views
0

これは私の最初のpythonプロジェクトですので、この問題はちょっとばかばかしいかもしれません。
マンデルブローレンダラーを作成しようとしています。チュートリアルやコードからコードをまとめて、何かを作るために理解しているコードです。
基本的にレンダラー用のGUIのすべての数学と基本機能がありますが、matplotlibグラフを実際にtkinter GUI内にグラフ化することはできません。
matplolibの表示部分は実際には実行するにはmandelbrot_image(-0.8,-0.7,0,0.1,cmap='hot')が必要な機能です。そのコードが導入されている場合、マンデルブロセットはプロットされていますが、別のmatplotlibウィンドウに表示されます。Matplotlibはtkinterの関数

ここに私のコードがあります。私は事前に感謝してもう一度謝ります。

#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 code 


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 

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) 


#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.3 

def mandelbrot_image(xmin,xmax,ymin,ymax,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, ax = plt.subplots(figsize=(width, height),dpi=72) 
    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(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] = 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 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() 
+0

私は恐ろしく汚いコード – Simon

+0

のために謝罪の代わりに使用すると、問題の[MCVE]を生産する上で自分のために働くことができ、コードのために謝罪しています。コードでは、 'mandelbrot_image()'関数が呼び出されないことを示しています!他のコードから一緒にいたずらしたコードにDonate-Buttonを入れて、ここで質問をするのはかなり皮肉です。質問に答えると、私は寄付の一部を得るだろうか??? – ImportanceOfBeingErnest

+0

私はそれについて、私に教えてくれてありがとう、その問題の最小、完全、および検証可能な例を作成します。寄付のことについては、実際の機能よりも冗談のほうが多いのですが、もしそれをやり遂げると、誰かがお金と半分焼いたプログラムを捨てるのに十分に豊かであれば私は部分を与えるでしょう。 – Simon

答えて

1

ここでの主な問題は、2つの異なる数字を作成することです。 Tkフレームに存在するものは、マンデルブロ画像を描くものではありません。
コード全体で同じ数字で作業する必要があります。
1つの方法は、mandelbrot_imageに図を作成させて戻し、後でFigureCanvasにそれを供給できるようにすることです。 完全な解決策については、以下を参照してください。

さらに、matplotlibにはfigshowメソッドがありません。おそらくimshow()が必要です。

import matplotlib 
matplotlib.use("TkAgg") 
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg 
from matplotlib.figure import Figure 

import Tkinter as tk 

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) 


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(cmap) 
    norm = colors.PowerNorm(gamma) 
    ax.imshow(z.T,cmap=cmap,origin='lower',norm=norm) 
    return fig 

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

      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 __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 inside 
     fig = mandelbrot_image() 
     # attach this figure to the TK canvas 
     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() 
関連する問題