Ceci est le premier post! J'ai hâte de travailler avec vous!
Il est possible de dessiner un graphique en temps réel dans l'interface graphique, et c'est un résumé à ce moment-là. Comme l'interface graphique utilisait wxpython, j'ai utilisé wx.lib.plot dans le même module wx. J'ai eu du mal à trouver des articles sur l'axe du temps, j'espère donc que vous le trouverez utile.
mac OS python 3.8.5 wxpython 4.1.0
python
import wx
import wx.lib
import wx.lib.plot as plot
Organisez dans l'ordre wx.Frame-> wx.Panel-> plot.Canvas.
python
import wx
import wx.lib
import wx.lib.plot as plot
#Utilisé pour le dessin graphique
import random
#Valeur à dessiner
x_val = list(range(10))
y_val = [random.randint(0, 10) for i in range(10)] # 0~10 valeurs aléatoires jusqu'à 10
# [(x1, y1), (x2, y2),...(xn, yn)]Transformé pour passer au graphique au format
xy_val = list(zip(x_val, y_val))
class MainFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(500, 500))
#création de panneaux
self.panel = wx.Panel(self, -1)
#création de graphes
self.plotter = plot.PlotCanvas(self, -1)
#Créer une ligne à afficher&dessin
line = plot.PolyLine(xy_val)
gc = plot.PlotGraphics([line])
self.plotter.Draw(gc)
#création de calibre&Installation
sizer = wx.GridSizer(1, 1, gap=(0, 0))
sizer.Add(self.plotter, flag=wx.EXPAND)
self.SetSizer(sizer)
#Afficher l'interface graphique au centre de l'écran
self.Center()
self.Show()
def main():
app = wx.App()
MainFrame(None, -1, 'WxLibPlot')
app.MainLoop()
if __name__ == '__main__':
main()
résultat
Ajouter un titre, une légende et une étiquette de graphique Activer la fonction de zoom ou de glisser Changer la taille de la police, la couleur et l'épaisseur de la ligne
Le zoom et le glissement ne peuvent pas coexister, donc activer l'un désactive l'autre.
Modifiez le code ci-dessous self.plotter = plot.PlotCanvas (self, -1) dans le code ci-dessus comme suit.
python
self.plotter.enableLegend = True #Définir l'affichage de la légende sur True
self.plotter.fontSizeTitle = 18 #Définissez la taille de police du titre du graphique sur 18.(Défaut=15)
self.plotter.fontSizeLegend = 18 #Définissez la taille de la légende sur 18.(Défaut=7)
self.plotter.fontSizeAxis = 18 #étiquette xy,Définissez la taille des caractères des coordonnées sur 18.(Défaut=10)
#Activez la fonction de zoom ou de glissement. Un seul peut être activé
# self.plotter.enableZoom = True
self.plotter.enableDrag = True
#Créer une ligne à afficher&dessin()
line = plot.PolyLine(xy_val, legend='sample', colour='red', width=4) #Ajout du texte de la légende, changement de la couleur de la ligne en rouge et de l'épaisseur à 4
gc = plot.PlotGraphics([line], 'WxLibPlot', 'xaxis', 'yaxis') #Titre du graphique, étiquette xy ajoutée
résultat Le glissement est activé.
Utilisez wx.Timer pour dessiner un graphique linéaire qui prend des valeurs aléatoires toutes les secondes. Cette fois, nous avons ajouté un bouton pour contrôler le début et la fin du tracé.
python
import wx
import wx.lib
import wx.lib.plot as plot
#Utilisé pour le dessin graphique
import random
class MainFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(500, 500))
#création de panneaux
self.panel = wx.Panel(self, -1)
#Bouton pour démarrer et arrêter la mesure
self.start_button = wx.Button(self, -1, label='start')
self.stop_button = wx.Button(self, -1, label='stop')
#création de graphes
self.plotter = plot.PlotCanvas(self, -1)
#Valeur initiale du point de tracé
self.x_val = 0
self.xy_val = []
self.plotter.enableLegend = True #Définir l'affichage de la légende sur True
self.plotter.fontSizeTitle = 18 #Définissez la taille de police du titre du graphique sur 18.(Défaut=15)
self.plotter.fontSizeLegend = 18 #Définissez la taille de la légende sur 18.(Défaut=7)
self.plotter.fontSizeAxis = 18 #étiquette xy,Définissez la taille des caractères des coordonnées sur 18.(Défaut=10)
#Activez la fonction de zoom ou de glissement. Un seul peut être activé
# self.plotter.enableZoom = True
# self.plotter.enableDrag = True
#Créer une ligne à afficher&dessin()
line = plot.PolyLine(self.xy_val, legend='sample', colour='red', width=2) #Ajout du texte de la légende, changement de la couleur de la ligne en rouge et de l'épaisseur à 4
gc = plot.PlotGraphics([line], 'RealTimePlot', 'xaxis', 'yaxis') #Titre du graphique, étiquette xy ajoutée
self.plotter.Draw(gc)
#Créer un minuteur d'images
self.timer = wx.Timer(self)
#création de calibre&Installation
sizer1 = wx.FlexGridSizer(2, 1, gap=(0, 0)) #Un calibreur pour organiser un graphique et un calibreur 2 par 1
sizer2 = wx.GridSizer(1, 2, gap=(0, 0)) #Sizer pour organiser les boutons sur 1 ligne et 2 colonnes
sizer1.Add(self.plotter, flag=wx.EXPAND) # flag=wx.EXPAND:Étendre la largeur et la hauteur au maximum
sizer1.Add(sizer2, flag=wx.ALIGN_RIGHT) # flag=wx.ALIGN_RIGHT:Installé à droite
sizer1.AddGrowableCol(0) #Étendre la largeur de la première ligne au maximum
sizer1.AddGrowableRow(0) #Étendre la hauteur de la première ligne au maximum
#Installation des boutons
sizer2.Add(self.start_button)
sizer2.Add(self.stop_button)
self.SetSizer(sizer1)
#Événements
self.start_button.Bind(wx.EVT_BUTTON, self.graph_start)
self.stop_button.Bind(wx.EVT_BUTTON, self.graph_stop)
self.Bind(wx.EVT_TIMER, self.graph_plot)
#Afficher l'interface graphique au centre de l'écran
self.Center()
self.Show()
def graph_start(self, event):
self.plotter.Clear() #Initialiser le graphique
self.x_val, self.xy_val = 0, [] # x_val, xy_Initialiser val
self.timer.Start(1000)
def graph_stop(self, event):
self.timer.Stop()
def graph_plot(self, event):
y_val = random.randint(0, 100)
self.xy_val.append((self.x_val, y_val))
line = plot.PolyLine(self.xy_val, legend='sample', colour='red', width=2)
gc = plot.PlotGraphics([line], 'RealTimePlot', 'xaxis', 'yaxis')
self.plotter.Draw(gc)
self.x_val += 1
def main():
app = wx.App()
MainFrame(None, -1, 'WxLibPlot')
app.MainLoop()
if __name__ == '__main__':
main()
résultat Après avoir appuyé sur le bouton de démarrage, il devient blanc une fois car le graphique est initialisé.
La méthode de dessin change en modifiant l'attribut appelé xSpec
python
self.plotter.xSpec = 'auto' # or 'min', int, (min, max), 'none'
À partir du haut, ce sera «auto», «min», int, (min, max). «auto» est la valeur par défaut. Si vous attribuez un type entier, le comportement est le même que "min", mais les coordonnées sont fixes. Dans l'exemple ci-dessus, le graphique est divisé en quatre et les coordonnées sont affichées sur la limite.
«aucun» est omis car il n'efface que l'axe des x et l'étiquette.
C'est la partie que je voulais le plus écrire. Immédiatement, j'écrirai le code et le résultat. L'intervalle de temps est de 1 seconde.
python
import datetime as dt
import random
import wx
import wx.lib
import wx.lib.plot as plot
class TimeAxisPlot(plot.PlotCanvas):
def __init__(self, parent, id):
plot.PlotCanvas.__init__(self, parent, id)
#Définir les relations de mise en page
self.enableLegend = True
self.fontSizeLegend = 18
self.fontSizeAxis = 18
self.xSpec = 4
self.startDate = dt.datetime.now()
self.data = []
line = plot.PolyLine(self.data, legend='sample', colour='red')
gc = plot.PlotGraphics([line], 'TimeAxisPlot', 'time', 'yaxis')
self.Draw(gc)
def _xticks(self, *args):
ticks = plot.PlotCanvas._xticks(self, *args)
# ticks = [(Points de tracé,Caractère à afficher), (),...()]
new_ticks = []
for tick in ticks:
t = tick[0]
time_value = self.startDate + dt.timedelta(seconds=t)
time_value_str = time_value.strftime('%H:%M:%S')
new_ticks.append([t, time_value_str])
# new_ticks = [(Points de tracé,Heures du jour), (),...()]
#Changer les caractères affichés en temps
return new_ticks
class MainFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(500, 500))
#création de panneaux
self.panel = wx.Panel(self, -1)
#Bouton pour démarrer et arrêter la mesure
self.start_button = wx.Button(self, -1, label='start')
self.stop_button = wx.Button(self, -1, label='stop')
#création de graphes
self.plotter = TimeAxisPlot(self, -1)
#Valeur initiale du point de tracé
self.x_val = 0
self.xy_val = []
self.plotter.enableLegend = True #Définir l'affichage de la légende sur True
self.plotter.fontSizeTitle = 18 #Définissez la taille de police du titre du graphique sur 18.(Défaut=15)
self.plotter.fontSizeLegend = 18 #Définissez la taille de la légende sur 18.(Défaut=7)
self.plotter.fontSizeAxis = 18 #étiquette xy,Définissez la taille des caractères des coordonnées sur 18.(Défaut=10)
#Créer une ligne à afficher&dessin()
line = plot.PolyLine(self.xy_val, legend='sample', colour='red', width=2) #Ajout du texte de la légende, changement de la couleur de la ligne en rouge et de l'épaisseur à 4
gc = plot.PlotGraphics([line], 'RealTimePlot', 'xaxis', 'yaxis') #Titre du graphique, étiquette xy ajoutée
self.plotter.Draw(gc)
#Créer un minuteur d'images
self.timer = wx.Timer(self)
#création de calibre&Installation
sizer1 = wx.FlexGridSizer(2, 1, gap=(0, 0)) #Un calibreur pour organiser un graphique et un calibreur 2 par 1
sizer2 = wx.GridSizer(1, 2, gap=(0, 0)) #Sizer pour organiser les boutons sur 1 ligne et 2 colonnes
sizer1.Add(self.plotter, flag=wx.EXPAND) # flag=wx.EXPAND:Étendre la largeur et la hauteur au maximum
sizer1.Add(sizer2, flag=wx.ALIGN_RIGHT) # flag=wx.ALIGN_RIGHT:Installé à droite
sizer1.AddGrowableCol(0) #Étendre la largeur de la première ligne au maximum
sizer1.AddGrowableRow(0) #Étendre la hauteur de la première ligne au maximum
#Installation des boutons
sizer2.Add(self.start_button)
sizer2.Add(self.stop_button)
self.SetSizer(sizer1)
#Événements
self.start_button.Bind(wx.EVT_BUTTON, self.graph_start)
self.stop_button.Bind(wx.EVT_BUTTON, self.graph_stop)
self.Bind(wx.EVT_TIMER, self.graph_plot)
#Afficher l'interface graphique au centre de l'écran
self.Center()
self.Show()
def graph_start(self, event):
self.plotter.Clear() #Initialiser le graphique
self.x_val, self.xy_val = 0, [] # x_val, xy_Initialiser val
self.timer.Start(1000)
def graph_stop(self, event):
self.timer.Stop()
def graph_plot(self, event):
y_val = random.randint(0, 100)
self.xy_val.append((self.x_val, y_val))
line = plot.PolyLine(self.xy_val, legend='sample', colour='red', width=2)
gc = plot.PlotGraphics([line], 'RealTimePlot', 'xaxis', 'yaxis')
self.plotter.Draw(gc)
self.x_val += 1
def main():
app = wx.App()
MainFrame(None, -1, 'TimeAxisPlot')
app.MainLoop()
if __name__ == '__main__':
main()
résultat
Inherit plot.Canvas pour créer une nouvelle classe, en remplaçant la méthode des coordonnées de l'axe x. ici,
python
def _xticks(self, *args):
ticks = plot.PlotCanvas._xticks(self, *args)
# ex)ticks = [(0, '0.0'), (0.5, '0.5'), (1.0, '1.0'), (1.5, '1.5'), (2.0, '2.0')]
# [(coordonnée x(float)), (coordonnée xに表示する文字(str))...]
ticks renvoie [(coordonnée x (flottant)), (caractère à afficher à la coordonnée x (str)) ...]. L'axe du temps est créé en remplaçant les caractères affichés par l'heure.
Méthode Créez un tuple de coordonnées et d'heure et ajoutez à la liste vide new_ticks ex) Heure de début: 0:00, ticks = [(0, '0.0'), (0.5, '0.5'), (1.0, '1.0'), (1.5, '1.5'), (2.0, '2.0' )]temps
pour la première phrase
python
new_ticks = []
for tick in ticks: #Boucle avec les tiques acquises
#0e taple(x points de coordonnées)Avoir
t = tick[0]
time_value = self.startDate + dt.timedelta(seconds=t)
time_value_str = time_value.strftime('%H:%M:%S')
new_ticks.append([t, time_value_str])
# new_ticks = [(Points de tracé,Heures du jour), (),...()]
#Changer les caractères affichés en temps
return new_ticks
Merci pour la lecture. Comme je l'ai remarqué lors de l'exécution, la vitesse de dessin la plus rapide était d'environ 0,05 s. Notez que la vitesse d'exécution n'a pas changé même si l'intervalle du minuteur était plus court que cela.
officiel wx.lib.plot — wxPython Phoenix 4.1.1a1 documentation
Référence pour le dessin en temps réel wxPython: dessin simultané d'animation et de dessin graphique
Référence de l'axe des temps [Note] Personnalisez l'échelle de l'axe y du tracé ─ wxPython wxPython-users - wx.lib.plot custom labels?
Recommended Posts