Koordinatensystem erstellen

Fragen zu Tkinter.
Antworten
Olsen
User
Beiträge: 17
Registriert: Donnerstag 16. Oktober 2014, 17:46

Guten "Abend",
ich habe vor, für meine Arbeit, eine Korngrößenverteilung mit Kurve zu erstellen. Dies ganze soll sich,in etwa, an der DIN 18123 orientieren.
Alle Eingaben sollen auf einer GUI getätigt werden. Das klappt auch ganz gut, das Koordinatensystem + Kurve krieg ich jedoch nicht richtig hin.
Der Quellcode ist vielleicht nicht wirklich übersichtlich, aber, wenn man ihn mal ausführt kann man ganz gut erkennen was ich will. Im unteren Teil werden die Eingaben getätigt, daraus werden die Durchgänge[%] berechnet. Dies geschieht auch wie gewollt. (Jaja, Layout ist miserabel, wird noch geändert ;)). (Probenmasse bis jetzt noch ohne Auswirkung, ist erstmal nicht wichtig)
Diese Durchgänge[in %] werden in einer Liste[D] gesammelt und sollen nachher auf der y-Achse liegen. Auf der x-Achse liegen die Siebe (in Liste[S] bereits eingetragen).

Code: Alles auswählen

from tkinter import *
from math import *
import matplotlib.pyplot as plt

#Fenster anlegen
F = Tk()
F.title("Korngrößenverteilung nach DIN 18123")
F.geometry("1200x500") 
F.update() 
u_max = F.winfo_width()-50 
v_max = F.winfo_height()-150 
F.geometry("") 
F.update() 

#Zeichenfläche anlegen
Hintergrundfarbe = "beige"
C = Canvas (F,width=u_max + 1, #+1, damit die Koordinaten von 0 bis u_max benutzbar sind
            height=v_max + 1,
            bg=Hintergrundfarbe,
            highlightthickness=0)

C.grid(column=0, row=0, columnspan=4)


#Durchgang
Label(text = "Durchgang [%]").grid(row = 1, column = 3)
                                   
#Eingabe Probenmasse
Label(text = "Probenmasse").grid(row = 1, column = 0, sticky = "w")
EProbenmasse = Entry(width = 15)
EProbenmasse.grid(row = 1, column = 1, sticky = "w")
Label(text = " g").grid(row = 1, column = 2)

#Eingabe Sieb 63,0 mm
Label(text = "Sieb1").grid(row = 2, column = 0, sticky = "w")
ESieb1 = Entry(width = 15)
ESieb1.grid(row = 2, column = 1, sticky = "w")
Label(text = " g").grid(row = 2, column = 2)

#Eingabe Sieb 31,5 mm
Label(text = "Sieb2").grid(row = 3, column = 0, sticky = "w")
ESieb2 = Entry(width = 15)
ESieb2.grid(row = 3, column = 1, sticky = "w")
Label(text = " g").grid(row = 3, column = 2)

#Eingabe Sieb 16,0 mm
Label(text = "Sieb3").grid(row = 4, column = 0, sticky = "w")
ESieb3 = Entry(width = 15)
ESieb3.grid(row = 4, column = 1, sticky = "w")
Label(text = " g").grid(row = 4, column = 2)

#Eingabe Sieb 8,0 mm
Label(text = "Sieb4").grid(row = 5, column = 0, sticky = "w")
ESieb4 = Entry(width = 15)
ESieb4.grid(row = 5, column = 1, sticky = "w")
Label(text = " g").grid(row = 5, column = 2)

#Eingabe Sieb 4,0 mm
Label(text = "Sieb5").grid(row = 6, column = 0, sticky = "w")
ESieb5 = Entry(width = 15)
ESieb5.grid(row = 6, column = 1, sticky = "w")
Label(text = " g").grid(row = 6, column = 2)

#Eingabe Sieb 2,0 mm
Label(text = "Sieb6").grid(row = 7, column = 0, sticky = "w")
ESieb6 = Entry(width = 15)
ESieb6.grid(row = 7, column = 1, sticky = "w")
Label(text = " g").grid(row = 7, column = 2)

#Eingabe Sieb 1,0 mm
Label(text = "Sieb7").grid(row = 8, column = 0, sticky = "w")
ESieb7 = Entry(width = 15)
ESieb7.grid(row = 8, column = 1, sticky = "w")
Label(text = " g").grid(row = 8, column = 2)

#Eingabe Sieb 0,5 mm
Label(text = "Sieb8").grid(row = 9, column = 0, sticky = "w")
ESieb8 = Entry(width = 15)
ESieb8.grid(row = 9, column = 1, sticky = "w")
Label(text = " g").grid(row = 9, column = 2)

#Eingabe Sieb 0,25 mm
Label(text = "Sieb9").grid(row = 10, column = 0, sticky = "w")
ESieb9 = Entry(width = 15)
ESieb9.grid(row = 10, column = 1, sticky = "w")
Label(text = " g").grid(row = 10, column = 2)

#Eingabe Sieb 0,125 mm
Label(text = "Sieb10").grid(row = 11, column = 0, sticky = "w")
ESieb10 = Entry(width = 15)
ESieb10.grid(row = 11, column = 1, sticky = "w")
Label(text = " g").grid(row = 11, column = 2)

#Eingabe Sieb 0,063 mm
Label(text = "Sieb11").grid(row = 12, column = 0, sticky = "w")
ESieb11 = Entry(width = 15)
ESieb11.grid(row = 12, column = 1, sticky = "w")
Label(text = " g").grid(row = 12, column = 2)

#Eingabe Schale
Label(text = "Schale").grid(row = 13, column = 0, sticky = "w")
ESchale = Entry(width = 15)
ESchale.grid(row = 13, column = 1, sticky = "w")
Label(text = " g").grid(row = 13, column = 2)


#Funktion für Knopf "Plot"

def Plot():
              
        #Liste erstellen
        #Siebe
        S = ["63.0","31.5","16.0","8.0","4.0","2.0","1.0","0.5","0.25","0.125","0.063"]
        
        #Durchgänge
        D = []
        #Eingabe
        Sieb1 = float(ESieb1.get())
        Sieb2 = float(ESieb2.get())
        Sieb3 = float(ESieb3.get())
        Sieb4 = float(ESieb4.get())
        Sieb5 = float(ESieb5.get())
        Sieb6 = float(ESieb6.get())
        Sieb7 = float(ESieb7.get())
        Sieb8 = float(ESieb8.get())
        Sieb9 = float(ESieb9.get())
        Sieb10 = float(ESieb10.get())
        Sieb11 = float(ESieb11.get())
        Schale = float(ESchale.get())
        #Verarbeitung
        Summe = Sieb1+Sieb2+Sieb3+Sieb4+Sieb5+Sieb6+Sieb7+Sieb8+Sieb9+Sieb10+Sieb11+Schale
        DSieb1 = 100-(Sieb1/Summe)*100
        DSieb2 = DSieb1-(Sieb2/Summe)*100
        DSieb3 = DSieb2-(Sieb3/Summe)*100
        DSieb4 = DSieb3-(Sieb4/Summe)*100
        DSieb5 = DSieb4-(Sieb5/Summe)*100
        DSieb6 = DSieb5-(Sieb6/Summe)*100
        DSieb7 = DSieb6-(Sieb7/Summe)*100
        DSieb8 = DSieb7-(Sieb8/Summe)*100
        DSieb9 = DSieb8-(Sieb9/Summe)*100
        DSieb10 = DSieb9-(Sieb10/Summe)*100
        DSieb11 = DSieb10-(Sieb11/Summe)*100
        DSchale = DSieb11-(Schale/Summe)*100
        #Ausgabe
        LDSieb1.config(text = "%.2f"%DSieb1)
        LDSieb2.config(text = "%.2f"%DSieb2)
        LDSieb3.config(text = "%.2f"%DSieb3)
        LDSieb4.config(text = "%.2f"%DSieb4)
        LDSieb5.config(text = "%.2f"%DSieb5)
        LDSieb6.config(text = "%.2f"%DSieb6)
        LDSieb7.config(text = "%.2f"%DSieb7)
        LDSieb8.config(text = "%.2f"%DSieb8)
        LDSieb9.config(text = "%.2f"%DSieb9)
        LDSieb10.config(text = "%.2f"%DSieb10)
        LDSieb11.config(text = "%.2f"%DSieb11)
        LDSchale.config(text = "%.2f"%DSchale)
        #in Liste D einfügen
        D.append(DSieb1)
        D.append(DSieb2)
        D.append(DSieb3)
        D.append(DSieb4)
        D.append(DSieb5)
        D.append(DSieb6)
        D.append(DSieb7)
        D.append(DSieb8)
        D.append(DSieb9)
        D.append(DSieb10)
        D.append(DSieb11)
        #plotten
        x = S
        y = D
        plt.plot(x,y)
        plt.show()

        
        

        
        

#Button "berechnen"
b1 = Button(text = "Plot", command = Plot)
b1.grid(row = 14, column = 0, columnspan = 4, sticky = "nsew")

#Ausgabe Durchgänge
LDSieb1 = Label()
LDSieb1.grid(row = 2, column = 3)
            
LDSieb2 = Label()
LDSieb2.grid(row = 3, column = 3)

LDSieb3 = Label()
LDSieb3.grid(row = 4, column = 3)

LDSieb4 = Label()
LDSieb4.grid(row = 5, column = 3)

LDSieb5 = Label()
LDSieb5.grid(row = 6, column = 3)

LDSieb6 = Label()
LDSieb6.grid(row = 7, column = 3)

LDSieb7 = Label()
LDSieb7.grid(row = 8, column = 3)

LDSieb8 = Label()
LDSieb8.grid(row = 9, column = 3)

LDSieb9 = Label()
LDSieb9.grid(row = 10, column = 3)
    
LDSieb10 = Label()
LDSieb10.grid(row = 11, column = 3)

LDSieb11 = Label()
LDSieb11.grid(row = 12, column = 3)

LDSchale = Label()
LDSchale.grid(row = 13, column = 3)



F.mainloop()


Nun zu meinem Problem:
Im oberen Teil soll eben ein Koordinatensystem enstehen:

x-Achse: 0-100, logarithmisch,
y-Achse: 0-100, linear.


Ich habe es bis jetzt nur geschafft es via matplotlib zu plotten. Dies öffnet natürlich ein neues Fenster, was nicht gewollt ist. Zudem sind dabei die Achsen auch nicht korrekt.


Ich hoffe Ihr versteht worauf ich hinaus will und könnt mir einen Denkanstoß geben. Es kann doch gar nicht so schwer sein :D

Mfg Olsen
Zuletzt geändert von Olsen am Sonntag 4. Januar 2015, 01:43, insgesamt 1-mal geändert.
Olsen
User
Beiträge: 17
Registriert: Donnerstag 16. Oktober 2014, 17:46

Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@Olsen: wenn Du im Forum Hilfe willst, lohnt es sich vielleicht, den Quellcode übersichtlich zu machen. Das erhöht die Motivation der Lesenden ungemein.
Wie man ein Matplotlib-Canvas in ein TK-Fenster bekommt, steht in der Matplotlib-Dokumentation, ebenso wie man logarithmische Plots macht. Dazu gibt es auch eine große Seite mit verschiedenen Plot-Beispielen, wo man sich das, das einem am besten passt, ganz einfach raussuchen kann.

Sobald Du anfängst, Variablen durchzunummerieren und Code zu kopieren, willst Du eigentlich Listen mit Schleifen benutzen. An wievielen Stellen müßtest Du etwas ändern, wenn ein Sieb dazukommt?
Auf Modulebene sollte kein Code stehen, bei GUIs bietet es sich an, für die Fenster Klassen zu verwenden.
Variablennamen sollten aussagekräftig sein und sich an die Namenskonvention halten, bei einzenen Großbuchstaben F,D,C,S ist das garantiert nicht der Fall.
Sternchenimporte sind schlecht, weil man nie genau weiß, was einem da in den eigenen Namensraum importiert wird, Du benutzt auch nichts aus math.

Ein Anfang könnte so aussehen:

Code: Alles auswählen

import tkinter as tk
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure

SIEBE = ["Sieb 63,0 mm", "Sieb 31,5 mm", "Sieb 16,0 mm", "Sieb 8,0 mm",
    "Sieb 4,0 mm", "Sieb 2,0 mm", "Sieb 1,0 mm", "Sieb 0,5 mm", "Sieb 0,25 mm",
    "Sieb 0,125 mm", "Sieb 0,063 mm", "Schale"]

class MainWindow(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.title("Korngrößenverteilung nach DIN 18123")

        self.fig = Figure(figsize=(5,4), dpi=100)
        self.canvas = FigureCanvasTkAgg(self.fig, master=self)
        self.canvas.get_tk_widget().grid(column=5, row=0, rowspan=14)

        tk.Label(self, text="Durchgang [%]").grid(row=1, column=3)

        tk.Label(self, text="Probenmasse").grid(row=1, column=0, sticky="w")
        self.probenmasse = tk.Entry(self, width=15)
        self.probenmasse.grid(row=1, column=1, sticky="w")
        tk.Label(self, text=" g").grid(row=1, column=2)

        self.siebe = []
        self.durchgaenge = []
        for row, sieb in enumerate(SIEBE, 2):
            tk.Label(self, text=sieb).grid(row=row, column=0, sticky="w")
            sieb = tk.Entry(self, width=15)
            sieb.grid(row=row, column=1, sticky="w")
            tk.Label(self, text=" g").grid(row=row, column=2)
            self.siebe.append(sieb)
            durch = tk.Label(self)
            durch.grid(row=row, column=3)
            self.durchgaenge.append(durch)

        b = tk.Button(self, text="Plot", command=self.plot)
        b.grid(row=14, column=0, columnspan=4, sticky="nsew")

    def plot(self):
        sieb = [float(s.get()) for s in self.siebe]
        gesamt = sum(sieb)
        durchgaenge = []
        d = 1.0
        for s, label in zip(sieb, self.durchgaenge):
            d -= s / gesamt
            durchgaenge.append(d)
            label.config(text="%.2f" % (d*100))
        x = [float(s.split()[1].replace(',', '.')) for s in SIEBE[:-1]]
        a = self.fig.add_subplot(111)
        a.set_xscale('log')
        a.plot(x, durchgaenge[:-1])
        self.canvas.show()


def main():
    win = MainWindow()
    win.mainloop()


if __name__ == '__main__':
    main()
Olsen
User
Beiträge: 17
Registriert: Donnerstag 16. Oktober 2014, 17:46

Hi Sirius3,
danke für die Tipps, ich denke daran kann man ganz gut erkennen, dass ich noch Neuling bin und mich nur ab und zu mit Python beschäftige. ;)

Werde mich mal mit der Dokumentation beschäftigen. Ist es richtig, dass es diese nur auf Englisch gibt?
Hase
User
Beiträge: 101
Registriert: Donnerstag 1. Oktober 2009, 15:17
Wohnort: Bremer Speckgürtel

Hallo,

ist das Tehma noch aktuell?


Habe selbst vor Jahren ein Programm für Korngrößenverteilungen geschrieben, allerdings mit einem völlig anderen Programmier-Ansatz. Das Programm ist schon etwas in die Jahre gekommen, wird aber bei uns immer noch produktiv eingesetzt. Eingabe über Web-Formulare (noch TurboGears 1.1), visuelle Kontrolle über dynamische SVG-Graphik, Ausdruck über MetaPost/LaTeX als pdf.

Bei Interesse könne wir uns gern mal austauschen.
Antworten