[PYTHON] Ich habe gerade ein Tool erstellt, mit dem Daten mithilfe der GUI-Operation einfach als Diagramm angezeigt werden können

Bei der Arbeit an der Datenanalyse denke ich, dass neben der numerischen Verfolgung der Daten häufig die Eigenschaften der Daten mithilfe von Diagrammen oder dergleichen visuell bestätigt werden. Es gibt viele solcher Aufgaben, und ich habe ein Tool namens "Glance" erstellt, mit dem Diagramme sofort angezeigt werden können, während die Datenkombination frei geändert werden kann. Ich habe Pythons tkinter Bibliothek verwendet, um die GUI zu erstellen.

Die Datei finden Sie unter hier. ** * Da es für die Verwendung in einer Windows-Umgebung erstellt wurde, muss es in einer Mac-Umgebung wahrscheinlich separat geändert werden ... **

Überblick

Es ist ein einfaches Werkzeug, das einfach aus den gelesenen Daten auswählt und diese als Grafik anzeigt. Es wurden drei Hauptoperationen implementiert.

  1. Lesen Sie die Daten aus der Dateiauswahl und zeigen Sie die Spalte in einer Liste an sample1.gif

  2. Wählen Sie Daten aus und zeigen Sie das Diagramm an

  1. Ändern Sie den Anzeigebereich des Diagramms dynamisch mit dem Schieberegler sample4.gif

Eine kurze Einführung in den süchtigen Teil

Informationen zum Übergeben von Werten innerhalb von tkinter

Ich habe tkinter dieses Mal zum ersten Mal verwendet, aber eines der Dinge, die hängen geblieben sind, ist "** Ich weiß nicht, wie ich den Rückgabewert der dem Widget zugewiesenen Funktion erhalten soll **". Zu diesem Zweck schien es notwendig zu sein, eine Klasse zu definieren, die Daten enthält, und diese zu übergeben, indem jedem Objekt Daten gegeben werden.

Im Fall dieses Tools gibt es beispielsweise eine Funktion namens "fileselect", die aus der Datei liest, aber der gelesene Datenrahmen wird nicht zurückgegeben, sondern an das Objekt im Prozess übergeben.

def fileselect():
    root = tkinter.Tk()
    root.withdraw()
    fTyp = [("", "*")]
    iDir = os.path.abspath(os.path.dirname(__file__))
    model.path = tkinter.filedialog.askopenfilename(filetypes=fTyp,
                                                    initialdir=iDir)

    suffix = model.path.rsplit('.', 1)[1]
    if suffix == 'csv' or suffix == 'pkl':
        model.set_data(suffix) #Ich habe die Daten hier.
        graph.config(state='active')
        Entry1.insert(tk.END, model.path)

        line_size = columns_list.size()
        columns_list.delete(0, line_size)
        for column in enumerate(model.data.columns):
            columns_list.insert(tk.END, column)
    else:
        tkinter.messagebox.showinfo(model.path, 'Wählen Sie eine CSV- oder Pickle-Datei aus.')

So aktualisieren Sie das Diagramm dynamisch

Beim Betrieb des tkinter-Widgets mit einer Funktion Sie definieren die Operationsfunktion innerhalb der Funktion im Bereich der Variablen.

Dieses Mal definieren wir auch "new_window", um das Diagramm in einem separaten Fenster zu öffnen Die Struktur der "Neuzeichnen" -Funktion, die das Diagramm aktualisiert, ist wie folgt.

def main():
    #wird bearbeitet
    def new_window():
        def redraw():
            #wird bearbeitet
        scale = tk.Scale(command=redraw) #Schiebeleiste

Dadurch wird die Neuzeichnungsfunktion jedes Mal ausgeführt, wenn Sie die Skala bearbeiten.

Das Innere der Redraw-Funktion ist frei, jedoch nach Änderung des von matplotlib ausgedrückten Inhalts Bitte beachten Sie, dass wenn "canvas.draw ()" nicht am Ende steht, dies nicht in der GUI angezeigt wird.

Ich kann den Code nicht trennen

Dies ist ein ungelöstes Problem, aber in meinem Schreibstil ist es in main () Ich konnte nicht als Funktion oder separate Datei ausgehen, da ich alle anderen Funktionen definiert habe. (Aber ich weiß nur, wie man das Widget mit einer Funktion bedient ...)

Infolgedessen wird main () lang und schwer zu lesen. Was ist falsch?

Ganzer Code

import os
import tkinter as tk
import tkinter.filedialog
import tkinter.messagebox

import japanize_matplotlib
from matplotlib.backends.backend_tkagg import (
    FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure
import numpy as np
import pandas as pd


def main():
    class model_data:
        def __init__(self):
            self.data = pd.DataFrame()
            self.path = ''
            self.columns = []

        def set_path(self, file_path):
            self.path = file_path

        def set_data(self, suffix):
            if suffix == 'csv':
                self.data = pd.read_csv(self.path)
            elif suffix == 'pkl':
                self.data = pd.read_pickle(self.path)

    def new_window(event):
        if any(model.data):
            def _quit_sub():
                sub_win.destroy()

            def _redraw(event):
                min_lim = min_scale.get()
                max_lim = max_scale.get()
                val = []
                if min_lim >= max_lim:
                    return
                else:
                    t = target.iloc[min_lim:max_lim, :]
                    for index in selection:
                        label = target.columns[index]
                        val.append(t[label].max())
                        val.append(t[label].min())

                    max_val = max(val)
                    min_val = min(val)

                ax.set_xlim(min_lim, max_lim)
                ax.set_ylim(min_val, max_val)
                canvas.draw()

            selection = columns_list.curselection()
            sub_win = tk.Toplevel(root)
            sub_win.configure(bg='white')
            sub_win.wm_title("Embedding in Tk")
            target = model.data.copy()
            target.reset_index(drop=True, inplace=True)
            fig = Figure(figsize=(10, 4), dpi=100)
            ax = fig.add_subplot(111)

            if norm_bln.get():
                for index in selection:
                    label = target.columns[index]
                    max_num = target[label].max()
                    min_num = target[label].min()

                    target[label] = (target[label] - min_num) / (max_num - min_num)
                    ax.plot(target.index,
                            target[label],
                            label=label)
            else:
                for index in selection:
                    label = target.columns[index]
                    ax.plot(target.index,
                            target[label],
                            label=label)
            canvas_frame = tk.Frame(master=sub_win, bg='white')
            canvas_frame.pack(side=tk.LEFT)
            canvas = FigureCanvasTkAgg(fig,
                                       master=canvas_frame)
            canvas.draw()
            canvas.get_tk_widget().pack(side=tk.TOP,
                                        fill=tk.BOTH,
                                        expand=1)
            control_frame = tk.Frame(master=sub_win)
            control_frame.pack(side=tk.RIGHT)
            toolbar = NavigationToolbar2Tk(canvas,
                                           canvas_frame)
            toolbar.update()
            canvas.get_tk_widget().pack(side=tk.TOP,
                                        fill=tk.BOTH,
                                        expand=True)

            min_scale = tk.Scale(control_frame,
                                 label='Min',
                                 orient='h',
                                 from_=0,
                                 bg='light blue',
                                 resolution=1,
                                 to=model.data.shape[0]-1,
                                 command=_redraw)
            min_scale.pack(anchor=tk.NW)
            max_scale = tk.Scale(control_frame,
                                 label='Max',
                                 orient='h',
                                 from_=1,
                                 bg='tan1',
                                 resolution=1,
                                 to=model.data.shape[0],
                                 command=_redraw)
            max_scale.set(target.shape[0])
            max_scale.pack(anchor=tk.NW)

            button = tkinter.Button(master=canvas_frame,
                                    text="Quit",
                                    command=_quit_sub)
            button.pack(side=tkinter.BOTTOM)
        else:
            tkinter.messagebox.showinfo('Glance.py', 'Bitte wählen Sie zuerst die zu lesenden Daten aus')

    def fileselect():
        root = tkinter.Tk()
        root.withdraw()
        fTyp = [("", "*")]
        iDir = os.path.abspath(os.path.dirname(__file__))
        model.path = tkinter.filedialog.askopenfilename(filetypes=fTyp,
                                                        initialdir=iDir)

        suffix = model.path.rsplit('.', 1)[1]
        if suffix == 'csv' or suffix == 'pkl':
            model.set_data(suffix)
            graph.config(state='active')
            Entry1.insert(tk.END, model.path)

            line_size = columns_list.size()
            columns_list.delete(0, line_size)
            for column in enumerate(model.data.columns):
                columns_list.insert(tk.END, column)
        else:
            tkinter.messagebox.showinfo(model.path, 'Wählen Sie eine CSV- oder Pickle-Datei aus.')

    def _quit(event):
        root.quit()
        root.destroy()

    root = tk.Tk()
    model = model_data()
    root.title('Glance')
    root.geometry('680x300')

    frame1 = tk.Frame(bd=3, relief=tk.SUNKEN, pady=5)
    frame1.pack(padx=5, pady=5, ipadx=10, ipady=10, side=tk.LEFT)
    Static1 = tk.Label(frame1, text='File Path')
    Static1.pack()

    Entry1 = tk.Entry(frame1, width=80)
    Entry1.insert(tk.END, model.path)
    Entry1.pack()

    Static1 = tk.Label(frame1, text='Column Names')
    Static1.pack()

    var = tk.StringVar(value=[])
    columns_list = tk.Listbox(frame1,
                              listvariable=var,
                              width=80,
                              selectmode='multiple')
    scrollbar = tk.Scrollbar(frame1,
                             command=columns_list.yview)

    columns_list.yscrollcommand = scrollbar.set
    scrollbar.pack(fill=tk.BOTH,
                   side=tk.RIGHT)
    columns_list.pack()

    Button1 = tk.Button(frame1,
                        text='SelectFile',
                        width=10,
                        command=fileselect)
    Button1.pack(pady=5)

    frame2 = tk.Frame()
    frame2.pack(padx=5, pady=5, ipadx=10, ipady=10, fill=tk.BOTH)

    norm_bln = tk.BooleanVar()
    norm_bln.set('False')
    norm = tkinter.Checkbutton(frame2,
                               variable=norm_bln,
                               text='Norm')
    norm.pack()

    graph = tk.Button(frame2,
                      text='Graph',
                      width=10,
                      state='disable')
    graph.bind("<Button-1>", new_window)
    graph.pack()

    frame3 = tk.Frame()
    frame3.pack(padx=5, pady=5, ipadx=10, ipady=10, side=tk.BOTTOM)
    Button2 = tk.Button(frame3, text='Exit', width=5)
    Button2.bind("<Button-1>", _quit)
    Button2.pack()

    root.mainloop()


if __name__ == "__main__":
    main()

Referenzseite

So zeigen Sie das Diagramm an und ändern es dynamisch Informationen zur Platzierung des tkinter-Widgets

Recommended Posts

Ich habe gerade ein Tool erstellt, mit dem Daten mithilfe der GUI-Operation einfach als Diagramm angezeigt werden können
Ich habe ein Skript erstellt, um Piktogramme anzuzeigen
Ich habe ein Tool erstellt, um Hy nativ zu kompilieren
Ich habe ein Tool erstellt, um neue Artikel zu erhalten
Ich habe ein Tool zur Erzeugung sich wiederholender Textdaten "rpttxt" erstellt.
Ich habe ein Tool erstellt, um eine Wortwolke aus Wikipedia zu erstellen
[Titan Craft] Ich habe ein Werkzeug gemacht, um einen Riesen nach Minecraft zu rufen
Verfahren von der Umgebungskonstruktion bis zum Betriebstest von testinfra, einem von Python erstellten Testwerkzeug für die Serverumgebung
Ich habe eine Bibliothek erstellt, die Konfigurationsdateien mit Python einfach lesen kann
Impressionen von Touch, einem von Python erstellten Datenvisualisierungstool
Ich habe den Befehl gegeben, einen farbenfrohen Kalender im Terminal anzuzeigen
Ich habe ein CLI-Tool erstellt, um Bilder in jedem Verzeichnis in PDF zu konvertieren
Ich habe ein Programm erstellt, um Sie per LINE zu benachrichtigen, wenn Schalter eintreffen
Ich habe ein Programm erstellt, um einzugeben, was ich gegessen habe, und um Kalorien und Zucker anzuzeigen
Ich habe ein Tool erstellt, um Jupyter py mit VS Code in ipynb zu konvertieren
Ich habe ein automatisches Stempelwerkzeug für den Browser erstellt.
Ich habe versucht, den Höhenwert von DTM in einem Diagramm anzuzeigen
Ich habe ein Tool erstellt, um die Ausführungszeit von cron zu schätzen (+ PyPI-Debüt)
Ich habe ein Tool zum Korrigieren von GPS-Daten mit der Map Matching API von Mapbox (Mapbox Map Matching API) erstellt.
Ich habe ein Tool erstellt, um Slack über Connpass-Ereignisse zu informieren, und es zu Terraform gemacht
Ich habe versucht zu erklären, wozu der Python-Generator so einfach wie möglich ist.
Ich habe ein Modul in C-Sprache erstellt, das von Python geladene Bilder filtert
Ich habe ein Tool zum Generieren von Markdown aus der exportierten Scrapbox-JSON-Datei erstellt
Link zu den Datenpunkten des von jupyterlab & matplotlib erstellten Diagramms
Ich habe ein Tool zum automatischen Sichern der Metadaten der Salesforce-Organisation erstellt
Ich möchte einfach ein Rauschmodell erstellen
Ich habe ein nützliches Tool für Digital Ocean erstellt
Ich habe eine GUI-App mit Python + PyQt5 erstellt
Wie auch immer, ich möchte JSON-Daten einfach überprüfen
Macht süchtig, wenn Kintone ein Datenspeicher ist
Ich habe ein Router-Konfigurationssammlungstool Config Collecor erstellt
Ich möchte leicht einen leckeren Laden finden
Ich habe mit Numpy eine Grafik mit Zufallszahlen erstellt
Ein cooles Diagramm zur Datenanalyse von Wiire!
Ich habe ein System erstellt, mit dem Sie nur durch einen Anruf twittern können
Ich habe vergessen, VIM zu bedienen, also habe ich ein Video zum Auswendiglernen gemacht. 3 Videos nach Level
Ich möchte Timeout einfach in Python implementieren
Lassen Sie uns Chat-Benutzerverwaltungstool gemacht
Ich habe eine Bibliothek erstellt, um japanische Sätze schön zu brechen
Ich habe ein Reinigungstool für Google Container Registry erstellt
Ich habe ein Skript erstellt, um ein Snippet in README.md einzufügen
Visualisieren Sie mit Cytoscape 2 Eisenbahnstreckendaten als Grafik
Ich habe ein Python-Modul erstellt, um Kommentare zu übersetzen
Ich habe einen Code erstellt, um illustration2vec in ein Keras-Modell zu konvertieren
Ich möchte einfach eine modellbasierte Entwicklungsumgebung erstellen
So zeigen Sie DataFrame als Tabelle in Markdown an
Ich habe einen Befehl zum Markieren des Tabellenclips gegeben
Ich habe eine Python-Bibliothek erstellt, die einen rollierenden Rang hat
Erstellt einen Toolsver, der Betriebssystem, Python, Module und Toolversionen an Markdown ausspuckt
Ich habe ein Tool erstellt, um die Antwortlinks von OpenAI Gym auf einmal zu erhalten
Ich habe eine Klasse erstellt, um das Analyseergebnis von MeCab in ndarray mit Python zu erhalten
Datenvisualisierung mit Python - Die Methode zum gleichzeitigen Zeichnen von Attribut-basierten Diagrammen mit "Facet" ist zu praktisch
Ich habe ein Tool erstellt, um automatisch ein einfaches ER-Diagramm aus der Anweisung CREATE TABLE zu generieren
Erstellt ein Tool, mit dem Sie bequem Parameter für Modelle des maschinellen Lernens festlegen können
Erstellt eine Methode zur automatischen Auswahl und Visualisierung eines geeigneten Diagramms für Pandas DataFrame
〇✕ Ich habe ein Spiel gemacht
Ich habe ein Paket erstellt, um Zeitreihen mit Python zu filtern
Ich habe eine Schachtel gemacht, um mich auszuruhen, bevor Pepper müde wird
unixtime ← → Ich habe versucht, eine Klasse zu erstellen, die die Datums- / Uhrzeitkonvertierung problemlos durchführt
Ich habe einen Befehl zum Generieren eines Kommentars für eine Tabelle in Django eingegeben
Ich habe eine Funktion erstellt, um das Modell von DCGAN zu überprüfen