2017-02-12 10 views
1

* txtファイルに基づいて関数をプロットするpythonでプログラムを作成する必要があります。このファイルには、最初の列に20 xの値(xの範囲は-10から10)が含まれ、次の列には20のyの値が含まれます。私は、ファイルを開くボタンでウィンドウを作成することに成功しました。また、軸などを描画しました。唯一の問題は、txtファイルから読み取った値がプログラムの座標に対応していないことです。これは私のコードです:tkinterを使ったPythonのグラフプロット

import tkinter as tk 
import tkinter.filedialog 


class Program(tk.Frame,tk.Canvas): 

def __init__(self, parent): 
    tk.Frame.__init__(self, parent) 
    self.parent = parent 
    self.kanwa = tk.Canvas(self) 
    self.kanwa.pack(fill=tk.BOTH, expand=1) 
    self.initUI() 
    self.rys_osi() 
    self.znaczniki() 


def initUI(self): 

    self.parent.title("Program") 
    self.pack(fill=tk.BOTH, expand=1) 

    menubar = tk.Menu(self.parent) 
    self.parent.config(menu=menubar) 

    fileMenu = tk.Menu(menubar) 
    fileMenu.add_command(label="Otwórz", command=self.otworz_plik) 
    menubar.add_cascade(label="Plik", menu=fileMenu) 
    self.kanwa.create_text(5, 5, anchor=tk.NW, font="Helvetica 18 bold", fill="blue", text="Wykres funkcji") #tytul 
    self.kanwa.create_text(780, 270, font="Helvetica 14 bold", fill="black", text="0X") #tytul OX 

def rys_osi(self): 
    self.kanwa.create_line(400, 600, 400, 0, arrow=tk.LAST, arrowshape=(13,17,6), width=3) #os y (x0,y0,x1,y1), grubosc 3px 
    self.kanwa.create_line(0, 300, 800, 300, arrow=tk.LAST, arrowshape=(13,17,6), width=3) #os x, domyslny arrowshape (d1,d2,d3=8,10,3) 

def znaczniki(self):  
    for i in range(21): 
     x = i * 38 
     self.kanwa.create_line(x+20,310,x+20,290, width=2)          #rysowanie znacznikow na osi x 
    for j in range(21): 
     y = j * 27 
     self.kanwa.create_line(410,y+30,390,y+30, width=2)          #rysowanie znacznikow na osi y 


def otworz_plik(self): 

    typ_pliku = [('Pliki tekstowe', '*.txt'), ('Wszystkie pliki', '*')]     #domyslny typ pliku - *txt 
    dlg = tk.filedialog.Open(self, filetypes = typ_pliku) 
    fl = dlg.show() 

    if fl != '': 
     text = self.czytaj_plik(fl) 
     self.konwersja(text) 

def czytaj_plik(self, filename): 

    f = open(filename, "r") 
    text = f.read() 
    return text 

def konwersja(self, text):     #OPERACJE NA WCZYTANYCH PUNTACH 
    x = [line.split()[0] for line in text.splitlines()] #podział wiersza na wartości x i y 
    y = [line.split()[1] for line in text.splitlines()] 
    x1 = [float(arg) for arg in x]      #konwersja x -> float 
    y1 = [float(arg) for arg in y]     #konwersja y -> float 
    punkty = zip (x1,y1)        #punkty (x,y) zzipowane funkcja 
    arg = max(abs(min(y1)),max(y1))      #maksymalna wartosc y 
    skala = arg/10         #podziel max wart y przez 10 - uzyskuje podzialke 
    wart_y = [] 

    for i in range (11): #petla wpisujaca wartosci skali y do listy wart_y 
     wart_y.append(i) #inicjalizacja listy ??? 
     wart_y[i]=skala*i 
    wart_y.reverse() #odwrocenie kolejnosci argumentow w liscie 
    print(x) 
    print(y) 
    print (arg,"MAX Y") 
    print(wart_y) 
    self.etykiety_x(x) 
    self.etykiety_y(wart_y) 
    self.rysuj(x1,y1) 

def etykiety_x(self,x):  
    for i in range(21): 
     q = i * 38 
     self.kanwa.create_text(q+15, 320, font="Helvetica 10", fill="black", text=x[i]) #etykiety osi x - po prostu nazywa od stringow 

def etykiety_y(self,wart_y):  
    for i in range(11): 
     q = i * 27 
     self.kanwa.create_text(430, q+30, font="Helvetica 10", fill="black", text=wart_y[i]) #etykiety osi y - dodatnie 
    j = 9 
    while j >= 0: 
     u = j * 27 
     self.kanwa.create_text(430, 570-u, font="Helvetica 10", fill="black", text=wart_y[j]) #etykiety osi y - ujemne 
     j=j-1 
     print(j,wart_y[j]) 

def rysuj(self,x1,y1): 
    punkty = [] 
    punkty = zip(x1,y1) 
    self.kanwa.create_line(*punkty, fill='red', width = 3) 


def main(): 

app = tk.Tk() 
Program(app) 
app.geometry("800x600") #rozmiar okna 
app.mainloop() 


if __name__ == '__main__': 
main() 

そしてTHXファイルは以下のようになります。

-10 150 
-9 114 
... 
10 190 

私は、コードでは非常に初心者ですので、私は上の座標に関数値を転化する方法がわかりません画面。

+0

今は正確には役に立ちませんが、 'tkinter'は数学的プロットの作成には苦労します。代わりに 'matplotlib'を使ってください:少なくとも将来のプロジェクトでは、http://matplotlib.org/。 –

+0

はい、私は知っていますが、私は外部ライブラリを使用せずにこれを行う必要があります。 –

答えて

0

私は一番下にあなたのif文のことがわかります:示すように

if __name__ == '__main__': main()

がインデントされなければなりません。

関連する問題