[PYTHON] Verarbeitung mehrerer Dateien mit Kivy + Matplotlib + Draw Graph auf der GUI

Während ich mich auf verschiedene Informationen im Internet bezog, studierte ich auch GUI und arbeitete an einem GUI-Programm, das Eingabe / Ausgabe + Verarbeitung + Grafik anzeigen kann.

Ausführungsumgebung

Windows10 Python 3.7.7 Kivy 1.11.1 GUI scheint in den letzten Jahren sehr beliebt zu sein, deshalb habe ich Kivy herausgefordert.

GUI gemacht

Die obere Zeile ist eine Schaltfläche für die Eingabe / Ausgabe und Verarbeitung von Dateien. Unterhalb der Schaltfläche befindet sich der Grafikanzeigebereich. Das Diagramm wird im Pulldown-Menü links ausgewählt und angezeigt.

AnalysisGUI.jpg

Code gemacht

Unten finden Sie die Codedetails. Der Code auf der Kivy-Seite beschreibt den Inhalt der GUI (Layout, Dateiauswahl, Funktion, die beim Drücken einer Taste aufgerufen werden soll usw.), und der Code auf der Python-Seite beschreibt die tatsächliche Verarbeitung. Erster Python

main.py


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import openpyxl
import os

from kivy.uix.boxlayout import BoxLayout
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.floatlayout import FloatLayout
from kivy.properties import ObjectProperty 
from kivy.uix.popup import Popup
from kivy.garden.matplotlib.backend_kivyagg import FigureCanvasKivyAgg

class LoadDialog(FloatLayout):
    load = ObjectProperty(None)
    cancel = ObjectProperty(None)
    Analysis = ObjectProperty(None)        
    current_dir = os.path.dirname(os.path.abspath(__file__))
 
class SaveDialog(FloatLayout):
    save = ObjectProperty(None)
    text_input = ObjectProperty(None)
    cancel = ObjectProperty(None)
    current_dir = os.path.dirname(os.path.abspath(__file__))  

class MainBoard(BoxLayout):
    file_name = ObjectProperty(None)
    info = ObjectProperty(None)
    bar_graph = ObjectProperty(None)
    lbl4spinner = ObjectProperty([])
    
    def __init__(self, **kwargs):
        super(MainBoard, self).__init__(**kwargs)
        self.master_flg = 0
        self.lbl=[]
        self.Data=[]
        
    def dismiss_popup(self):
        self._popup.dismiss()

    def show_load(self):
        content = LoadDialog(load=self.load, cancel=self.dismiss_popup, Analysis=self.Analysis)
        self._popup = Popup(title="Load file", content=content,size_hint=(0.9, 0.9))
        self._popup.open()

    def show_save(self):
        if self.master_flg==0:
            self.info.text = 'Load masterfile first, please'
        else:
            content = SaveDialog(save=self.save, cancel=self.dismiss_popup)
            self._popup = Popup(title="Save file", content=content, size_hint=(0.9, 0.9))
            self._popup.open()

    def load(self, path, filename, chkflg):
        try:
            if chkflg==1:
                self.file_name.text=str(filename.pop(0))
            else:
                self.file_name.text=str(filename[0])
        except Exception as e:
            self.info.text=str(type(e))+' : '+str(e) 
            
        Matrix=pd.DataFrame([])
        for i in range(len(filename)):
            NewData = pd.read_excel(filename[i])
            tmp_Data=NewData.iloc[0:,1:]
            tmp_Data.index=NewData.iloc[:,0]
            Matrix=pd.concat([Matrix,tmp_Data])
        
        self.lbl=list(Matrix.index)
        self.Data = Matrix
        self.dismiss_popup()
    
    def save(self, path, dirname):
        with pd.ExcelWriter(os.path.join(path, dirname)) as writer:
            self.Data.to_excel(writer)  
        self.dismiss_popup()         
    
    def Analysis(self):
        try:
            self.Data=self.Data*2
            self.lbl4spinner=map(str,self.lbl)#Liste, die an den Spinner weitergegeben werden soll
            self.master_flg=1
            self.info.text = 'Analysis completed!'
        except Exception as e:
            self.info.text=str(type(e))+' : '+str(e) 
    
    def on_spinner_select(self,text):
        row_no=self.lbl.index(text)
        Forgraph=self.Data.iloc[row_no,:]
        plt.clf()
        bar_plt=plt.bar(Forgraph.index, Forgraph)
        self.ids.bar_graph.clear_widgets()
        self.ids.bar_graph.add_widget(FigureCanvasKivyAgg(plt.gcf()))
        
class MainApp(App):
    title = 'Analyse'
    def build(self):
        return MainBoard()
        
if __name__ == '__main__':
    MainApp().run()

Dann Kivy

main.kv


<MainBoard>:
    info: info
    file_name: file_name
    bar_graph: bar_graph
    
    
    BoxLayout:
        orientation: 'vertical'
        pos: root.pos
        size: root.size
        
        canvas.before:
            Color: 
                rgba: 0.9, 0.9, 0.9, 1
            Rectangle:
                pos: self.pos
                size: self.size
                
        Label:
            id : info
            text: 'load file first, please'
            size_hint_y: 0.1
            canvas.before:
                Color: 
                    rgba: 0, 0, 0, 1
                Rectangle:
                    pos: self.pos
                    size: self.size
            
        BoxLayout:
            orientation: 'horizontal'
            size_hint_y: 0.1
            
            TextInput:
                id: file_name
                font_size: 12
                size_hint_x: 0.7
                           
        BoxLayout:
            orientation: 'horizontal'
            size_hint_y: 0.1
            
            Button:
                text: 'Load & Analysis'
                size_hint_x: 0.2
                on_press: root.show_load()
                
            Button:
                text: 'Save data'
                size_hint_x: 0.2
                on_press: root.show_save()
                 
            Button:
                text: "Exit"
                id: btnExit
                size_hint_x: 0.2               
                on_press: app.root_window.close()  

        BoxLayout:
            orientation: 'horizontal'
            size_hint_y: 0.7
   
            Spinner:
                text: "No."
                values: root.lbl4spinner
                size_hint: 0.1, 0.1
                pos_hint: {'center_x': .5, 'center_y': .5}
                on_text: root.on_spinner_select(self.text)
                
            BoxLayout:
                id: bar_graph
                
<LoadDialog>:

    BoxLayout:
        size: root.size
        pos: root.pos
        orientation: "vertical"
            
        FileChooser:
            id: filechooser
            path:root.current_dir
            multiselect: True
            filters: ['*.xlsx']
            FileChooserIconLayout

        BoxLayout:
            size_hint_y: None
            height: 30
 
            Button:
                text: "Load selected file(s)"
                on_press: root.load(filechooser.path, filechooser.selection,0)
                on_release: root.Analysis()
                
            Button:
                text: "Load all files"
                on_press: root.load(filechooser.path,filechooser.files,1)
                on_release: root.Analysis()
            
            Button:
                text: "Cancel"
                on_release: root.cancel()
                
<SaveDialog>:
   
    BoxLayout:
        size: root.size
        pos: root.pos
        orientation: "vertical"
        
        BoxLayout:
            size_hint_y: 0.1
            Button:
                text: 'ListView'
                on_release: filechooser.view_mode = 'list'
            Button:
                text: 'IconView'
                on_release: filechooser.view_mode = 'icon'
                
        FileChooser:
            id: filechooser
            path:root.current_dir
            on_selection: dir_name.text = self.selection and self.selection[0] or ''
            filters: ['*.xls','*.xlsx']
            FileChooserListLayout

        TextInput:
            id: dir_name
            size_hint_y: None
            height: 30
            multiline: False

        BoxLayout:
            size_hint_y: None
            height: 30

            Button:
                text: "Save"
                on_release: root.save(filechooser.path, dir_name.text)         
                            
            Button:
                text: "Cancel"
                on_release: root.cancel()

Kommentar

Das Basisprogramm verwendet Kivys Filechooser. Filechooser selbst hat offizielle Dokumente und Erklärungen vieler Vorfahren, daher wird es weggelassen. Ich werde nur erklären, wo ich gestolpert bin.

Zur Vereinfachung des Ablaufs fließt das Programm nicht von oben, sondern wechselt zwischen dem Kivy-Code und dem Py-Code hin und her, sodass ich den Ablauf erläutern werde.

1 Dateiauswahl

main.kv


            Button:
                text: 'Load & Analysis'
                size_hint_x: 0.2
                on_press: root.show_load()

main.py


    def show_load(self):
        content = LoadDialog(load=self.load, cancel=self.dismiss_popup, Analysis=self.Analysis)
        self._popup = Popup(title="Load file", content=content,size_hint=(0.9, 0.9))
        self._popup.open()

--Kivys LoadDialog-Code. Wählen Sie in FileChooser die Datei aus. Dieses Mal wird davon ausgegangen, dass die Originaldaten im xlsx-Format gespeichert sind. Es wird gefiltert, damit Dateien in unnötigen Formaten nicht angezeigt werden. Außerdem wird Multiselect als True angegeben, damit mehrere Dateien ausgewählt werden können. Die ID ist eine Variable namens filechooser, die die Adresse der ausgewählten Datei enthält.

main.kv


        FileChooser:
            id: filechooser
            path:root.current_dir
            multiselect: True
            filters: ['*.xlsx']
            FileChooserIconLayout

main.kv


        BoxLayout:
            size_hint_y: None
            height: 30
 
            Button:
                text: "Load selected file(s)"
                on_press: root.load(filechooser.path, filechooser.selection,0)
                on_release: root.Analysis()
                
            Button:
                text: "Load all files"
                on_press: root.load(filechooser.path,filechooser.files,1)
                on_release: root.Analysis()
            
            Button:
                text: "Cancel"
                on_release: root.cancel()

2 Datei lesen

main.pv


    def load(self, path, filename, chkflg):
        try:
            if chkflg==1:
                self.file_name.text=str(filename.pop(0))
            else:
                self.file_name.text=str(filename[0])
        except Exception as e:
            self.info.text=str(type(e))+' : '+str(e) 

--Lesen Sie als nächstes die Daten. In diesem xlsx wird der Parametername in Spalte A und die Datennummer in die erste Zeile eingegeben.

main.pv


        Matrix=pd.DataFrame([])
        for i in range(len(filename)):
            NewData = pd.read_excel(filename[i])
            tmp_Data=NewData.iloc[0:,1:]
            tmp_Data.index=NewData.iloc[:,0]
            Matrix=pd.concat([Matrix,tmp_Data])
        
        self.lbl=list(Matrix.index)
        self.Data = Matrix
        self.dismiss_popup()

3. 3. Analyse

main.pv


    def Analysis(self):
        try:
            self.Data=self.Data*2
            self.lbl4spinner=map(str,self.lbl)#Liste, die an den Spinner weitergegeben werden soll
            self.master_flg=1
            self.info.text = 'Analysis completed!'
        except Exception as e:
            self.info.text=str(type(e))+' : '+str(e) 

Vier. Grafikanzeige

main.kv


            Spinner:
                text: "No."
                values: root.lbl4spinner
                size_hint: 0.1, 0.1
                pos_hint: {'center_x': .5, 'center_y': .5}
                on_text: root.on_spinner_select(self.text)
                
            BoxLayout:
                id: bar_graph

main.py


    def on_spinner_select(self,text):
        row_no=self.lbl.index(text)
        Forgraph=self.Data.iloc[row_no,:]
        plt.clf()
        bar_plt=plt.bar(Forgraph.index, Forgraph)
        self.ids.bar_graph.clear_widgets()
        self.ids.bar_graph.add_widget(FigureCanvasKivyAgg(plt.gcf()))

5.Save --Save wird weggelassen, da es wie Load verarbeitet wird.

6. Andere

main.py


class MainBoard(BoxLayout):
    file_name = ObjectProperty(None)
    info = ObjectProperty(None)
    bar_graph = ObjectProperty(None)
    lbl4spinner = ObjectProperty([])

main.kv


<MainBoard>:
    info: info
    file_name: file_name
    bar_graph: bar_graph

main.py


    def __init__(self, **kwargs):
        super(MainBoard, self).__init__(**kwargs)
        self.master_flg = 0
        self.lbl=[]
        self.Data=[]

Websites, die gepflegt wurden

Ich habe insbesondere auf die Informationen zu Kivy auf der folgenden Website verwiesen. offizielles Dokument von kivy: Filechooser Immerhin ist das erste das offizielle Dokument. Sehnsucht nach Freiberuflern Es war hilfreich als Ausgangspunkt. Auf das Layout dieser GUI wird auch hier verwiesen. narito blog Es war sehr hilfreich, um die Beziehung zwischen Kivy und Python zu verstehen. stackoverflow : Python - Kivy framework - Spinner values list Listenanzeige für Spinner, ich glaube, ich wäre ohne diesen Beitrag festgefahren.

Was ich in Zukunft verbessern möchte

Ich verwende IDs zum Zeichnen von Diagrammen, möchte dies jedoch mit Object Propaty beschreiben.

Recommended Posts

Verarbeitung mehrerer Dateien mit Kivy + Matplotlib + Draw Graph auf der GUI
Zeichne Japanisch mit matplotlib auf Ubuntu
Zeichnen Sie mit matplotlib ein loses Diagramm
Zeichnen Sie ein Diagramm mit der PySimple-Benutzeroberfläche
So zeichnen Sie mit matplotlib ein Balkendiagramm, das mehrere Serien zusammenfasst
Zeichnen Sie eine flache Oberfläche mit einem Matplotlib-3D-Diagramm
Zeichnen Sie ein Diagramm, indem Sie es mit Pandas groupby verarbeiten
[Python] Zeichnen mehrerer Diagramme mit Matplotlib
Zeichnen Sie ein Faltlinien- / Streudiagramm mit Python Matplotlib für die CSV-Datei (2 Spalten).
Banddiagramm mit Matplotlib
[Python] Wie zeichnet man mit Matplotlib ein Liniendiagramm?
Mathematik mit Python studieren: Zeichnen Sie mit matplotlib ein Sympy-Diagramm (Scipy-Diagramm)
Zeichnen Sie Excel-Daten mit matplotlib (1)
Zeichnen Sie mit NetworkX ein Diagramm
Zeichnen Sie eine netCDF-Datei mit Python
Diagrammzeichnungsmethode mit matplotlib
Zeichnen Sie Excel-Daten mit matplotlib (2)
SVG-Diagramm mit matplotlib mit Heroku erstellen (auf Japanisch angezeigt)
Zeichnen Sie mit networkx ein Diagramm
Animieren Sie mehrere Diagramme mit matplotlib
Zeichne ein Diagramm mit Julia + PyQtGraph (2)
matplotlib: Kommentar in Zeitachsendiagramm einfügen
Zeichne ein Diagramm mit Julia + PyQtGraph (1)
Zeichne ein Diagramm mit Julia + PyQtGraph (3)
Zeichnen Sie mit Matplotlib ein Diagramm der Retentionsrate
Zeichnen Sie ein Diagramm mit Pandas + XlsxWriter
Zeichnen Sie einfach Diagramme mit matplotlib
Zeichne Riapnov Fractal mit Python, matplotlib
Erstellen einer GUI-Anwendung durch Kivy (einschließlich Matplotlib)
(Matplotlib) Ich möchte ein Diagramm mit einer in Pixel angegebenen Größe zeichnen
Wie man mit matplotlib mehrere Figuren betitelt
[Python] Legen Sie den Diagrammbereich mit matplotlib fest
GUI-Programmierung mit kivy ~ Teil 4 Verschiedene Tasten ~
So zeichnen Sie ein Diagramm mit Matplotlib
Zeigen Sie das xy-Diagramm von Matplotlib mit PySimpleGUI an.
Zeichnen Sie mit ArcPy eine Figur auf dem Feature-Layer
Auswahl des Boxbereichs per GUI auf dem Matplotlib-Plot
Schreiben Sie SVG-Diagramme mit Matplotlib mit Heroku
Zeichnen Sie eine hierarchische Achsenbeschriftung mit matplotlib + pandas
Richtlinienbasiertes Routing auf Computern mit mehreren Netzwerkkarten
Zeichnen Sie Dreiecksfunktionen mit Numpy und Matplotlib
Zeichnen Sie einfach ein Diagramm, indem Sie eine Datei angeben
Zeichnen Sie ein Diagramm mit PyQtGraph Part 1-Drawing
Erstellen Sie ein Diagramm mit Rändern, die mit matplotlib entfernt wurden