wxPython: Gleichzeitiges Zeichnen von Animationen und Grafiken

[Deep Q Learning mit Chainer - Launch-- Qiita](http://qiita.com/chachay/items/5fdb7c64af68bcacf7d3#wxpython%E3%81%AE%E4%BD%BF%E3%81%84 % E6% 96% B9) Ich habe es nicht verstanden

Ich möchte am unteren Bildschirmrand ein Diagramm hinzufügen

Es ist eine ergänzende Lektion. 002.gif

Umgebung

Vorbereitung

Die Windows-Installationsversion von wx.lib.plot hat einen Fehler in plot.py und kann nicht zeichnen. Schreiben Sie C: \ Python27 \ Lib \ site-packages \ wx-3.0-msw \ wx \ lib \ plot.py neu.

Die Quelle zum Umschreiben ist die neueste Version von Github ⇒ hier wxPython / plot.py at master · wxWidgets / wxPython

Referenz: Crash on pyplot demo - Google Groups

importieren

Kein besonderer Einfallsreichtum

python


import wx
import wx.lib
import wx.lib.plot as plot

Fensterrahmen vorbereiten

Plötzlich komme ich zu dem Schluss, Frame->Panel -> BoxSizer-> Plot (Animation) -> PlotCanvas Definieren Sie einfach das Bedienfeld usw. mit der hängenden Struktur und zeichnen Sie die Animation und das Diagramm.

python


class MyWindow(wx.Frame):
    def __init__(self, parent=None, id=-1, title=None):
        wx.Frame.__init__(self, parent, id, title)

        self.MainPanel = wx.Panel(self, size=(640, 480))
        
        self.panel = wx.Panel(self.MainPanel, size=(300, 480))
        self.panel.SetBackgroundColour('WHITE')
        
        self.plotter = plot.PlotCanvas(self.MainPanel, size=(340, 480))
        self.plotter.SetEnableZoom(False)
        self.plotter.SetEnableLegend(True)
        self.plotter.SetFontSizeLegend(20)
        
        self.i = 0
        self.data = []
        line = plot.PolyLine(self.data, legend='Dummy', colour='pink', width=2)
        self.gc = plot.PlotGraphics([line], 'Line Graph', 'X Axis', 'Y Axis')
        self.plotter.Draw(self.gc, xAxis=(0,15), yAxis=(0,15))      
        self.plotter.SetFontSizeLegend(point=10.5)
        
        mainSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainSizer.Add(self.panel)
        mainSizer.Add(self.plotter)
        
        self.SetSizer(mainSizer)

        self.Fit()

Grafikaktualisierung während der Animation

Ich animiere mit OnTimer, füge aber am Ende einfach ein Grafik-Update hinzu

python


        self.data.append((self.i, groundH - self.ball.pos_y))
        if len(self.data) >= 100:
            self.data = self.data[-101:]

        line = plot.PolyLine(self.data, legend='Pos Y', colour='red', width = 1)
        self.gc = plot.PlotGraphics([line], 'Line Graph', 'X Axis', 'Y Axis')
        self.plotter.Draw(self.gc, xAxis=(max(0,self.i-100), self.i), yAxis=(0, groundH))
        self.i += 1

Alle Code

python


# -*- coding: utf-8 -*-
import wx
import wx.lib
import wx.lib.plot as plot

import math

dT = 20
g  = 640.0
groundH = 410

class Ball(object):
    def __init__(self, panel, x, y, color):
        self.pos_x = float(x)
        self.pos_y = float(y)
        
        self.vx = 0.0
        self.vy = 0.0
        
        self.rad = 10.0
                
        self.pos_x_max, self.pos_y_max = panel.GetSize()
        self.B_color = color
        self.P_color = wx.Colour(50,50,50)
 
    def Move(self, ax = 0.0, ay = 0.0):
        self.vx += ax * dT / 1000.0
        self.vy += ay * dT / 1000.0
    
        self.pos_x += self.vx * dT / 1000.0
        self.pos_y += self.vy * dT / 1000.0
    
        self.pos_x = max(0, min(self.pos_x, self.pos_x_max))
        self.pos_y = max(0, min(self.pos_y, groundH))
 
    def Draw(self, dc):
        dc.SetPen(wx.Pen(self.P_color))
        dc.SetBrush(wx.Brush(self.B_color))
        dc.DrawCircle(self.pos_x, self.pos_y, self.rad)
        
    def IntersectBall(self, p0, v0):
        o = [-self.pos_x + p0[0], -self.pos_y + p0[1]]
                
        a = v0[0] ** 2 + v0[1] **2
        b = 2 * (o[0]*v0[0]+o[1]*v0[1])
        c = o[0] ** 2 + o[1] **2 - self.rad ** 2
        
        discriminant = float(b * b - 4 * a * c)
        
        if discriminant < 0:
            return [False, 1.0]
        
        discriminant = discriminant ** 0.5
        
        t1 = (- b - discriminant)/(2*a)
        t2 = (- b + discriminant)/(2*a)
        
        if t1 >= 0 and t1 <= 1.0:
            return [True, t1]

        if t2 >= 0 and t2 <= 1.0:
            return [True, t2]

        return [False, 1.0]         

class Walls(object):
    def __init__(self, x0, y0, x1, y1):
        self.xList = [x0, x1]
        self.yList = [y0, y1]
        self.P_color = wx.Colour(50,50,50)

    def addPoint(self, x, y):
        self.xList.append(x)
        self.yList.append(y)

    def Draw(self,dc):
        dc.SetPen(wx.Pen(self.P_color))
        for i in range(0, len(self.xList)-1):
            dc.DrawLine(self.xList[i], self.yList[i], self.xList[i+1],self.yList[i+1])

class MyWindow(wx.Frame):
    def __init__(self, parent=None, id=-1, title=None):
        wx.Frame.__init__(self, parent, id, title)

        self.MainPanel = wx.Panel(self, size=(640, 480))
        
        self.panel = wx.Panel(self.MainPanel, size=(300, 480))
        self.panel.SetBackgroundColour('WHITE')
        
        self.plotter = plot.PlotCanvas(self.MainPanel, size=(340, 480))
        self.plotter.SetEnableZoom(False)
        self.plotter.SetEnableLegend(True)
        self.plotter.SetFontSizeLegend(20)
        
        self.i = 0
        self.data = []
        line = plot.PolyLine(self.data, legend='Dummy', colour='pink', width=2)
        self.gc = plot.PlotGraphics([line], 'Line Graph', 'X Axis', 'Y Axis')
        self.plotter.Draw(self.gc, xAxis=(0,15), yAxis=(0,15))      
        self.plotter.SetFontSizeLegend(point=10.5)
        
        mainSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainSizer.Add(self.panel)
        mainSizer.Add(self.plotter)
        
        self.SetSizer(mainSizer)

        self.Fit()
        
        self.ball = Ball(self.panel, 150, 100, wx.Colour(237,125,49))
        
        # OutrBox
        self.Box = Walls(299, 479, 0, 479)
        self.Box.addPoint(1,1)
        self.Box.addPoint(299,1)
        self.Box.addPoint(299,480)
        
        # Ground
        self.Ground = Walls(0, 420, 300, 420)
        self.HitGround = False
 
        self.Bind(wx.EVT_CLOSE, self.CloseWindow)
 
        self.cdc = wx.ClientDC(self.panel)
        w, h = self.panel.GetSize()
        self.bmp = wx.EmptyBitmap(w,h)
 
        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.OnTimer)
        self.timer.Start(dT)
 
    def CloseWindow(self, event):
        self.timer.Stop()
        wx.Exit()
 
    def OnTimer(self, event):
        self.bdc = wx.BufferedDC(self.cdc, self.bmp)
        self.gcdc = wx.GCDC(self.bdc)

        self.gcdc.Clear()
 
        if self.HitGround and self.ball.vy > 0.1:
            self.ball.vy *= -0.8
        
        if (0.5*self.ball.vy **2 + g * (groundH - self.ball.pos_y)) < g *(groundH - 408) \
            and (groundH - self.ball.pos_y) < 2.0:
            ay = - ((groundH * g * 2.0 * 0.8) ** 0.5 / dT * 1000)
        else:
            ay = g
        
        self.ball.Move(ay = ay)
        self.HitGround,_ = self.ball.IntersectBall([0,420], [300, 0])        

        self.gcdc.SetPen(wx.Pen('white'))
        self.gcdc.SetBrush(wx.Brush('white'))
        self.gcdc.DrawRectangle(0,0,300,480)

        self.ball.Draw(self.gcdc)
        self.Box.Draw(self.gcdc)
        self.Ground.Draw(self.gcdc)
        
        self.data.append((self.i, groundH - self.ball.pos_y))
        if len(self.data) >= 100:
            self.data = self.data[-101:]

        line = plot.PolyLine(self.data, legend='Pos Y', colour='red', width = 1)
        self.gc = plot.PlotGraphics([line], 'Line Graph', 'X Axis', 'Y Axis')
        self.plotter.Draw(self.gc, xAxis=(max(0,self.i-100), self.i), yAxis=(0, groundH))
        self.i += 1

 
if __name__ == '__main__':
    app = wx.PySimpleApp()
    w = MyWindow(title='Bounce Ball')
    w.Center()
    w.Show()
    app.MainLoop()

Recommended Posts

wxPython: Gleichzeitiges Zeichnen von Animationen und Grafiken
Visualisieren Sie Daten und erfassen Sie gleichzeitig die Korrelation
Durchsuchen Sie .loc und .iloc gleichzeitig in pandas DataFrame
Hinter dem Graph Drawing Algorithmus und Networkx
Zeichnen Sie mit Pythons Matplotlib mehrere Karten und Daten gleichzeitig
Schleifen Sie gleichzeitig Variablen in der Vorlage
Ich möchte gleichzeitig einen Musik-Player erstellen und Musik ablegen
Ich habe die gleiche Datenanalyse mit kaggle notebook (python) und PowerBI gleichzeitig versucht ②
Verfahren zum gleichzeitigen Ändern des Tabellennamens und des Spaltennamens des Django-Modells
Ich habe die gleiche Datenanalyse mit kaggle notebook (python) und PowerBI gleichzeitig versucht ①
In Python integrierte Funktion ~ divmod ~ Lassen Sie uns gleichzeitig den Quotienten und den Rest der Division erhalten
python Hinweis: enumerate () - Index und Element der Liste gleichzeitig abrufen und zur Anweisung wenden
[Python 3.8 ~] Schreiben Sie Arrays usw. gleichzeitig mit der Definition neu [Tipps]
Technik, um das Zeichnen des Bildschirms zu beenden und die Wartezeit für das Backen zu verkürzen
Richten Sie einen Server ein, der mehrere Verbindungen gleichzeitig verarbeitet
[Python] So öffnen Sie zwei oder mehr Dateien gleichzeitig
Rufen Sie den Python-Debugger jederzeit auf
Zeichnen Sie ein Diagramm mit PyQtGraph Part 1-Drawing
Python open und io.open sind gleich
Stellen Sie sicher, dass die Vorverarbeitung zum Zeitpunkt der Erstellung und Vorhersage des Vorhersagemodells ausgerichtet ist
Typkonvertierung mehrerer Spalten von Pandas DataFrame mit Astype gleichzeitig
Drehen Sie in Python mehrere Listen mit for-Anweisung gleichzeitig