Seite 1 von 1

Matplotlib y_achse bei live Graph festsetzen

Verfasst: Dienstag 2. Juni 2020, 12:57
von Finn_h
Hallo,
Ich möchte aktuelle Temperaturdaten (hier mit random.randint simuliert) in einen live Graphen schreiben. Alte Werte sollen nach links "rausgedrückt" werden. Das funktioniert auch soweit, nur dass meine y-Achse sich seltsam verhält. Normalerweise sollten größere Wert höher stehen als kleinere Werte. Bei mir werden die allerdings einfach nach der Reihenfolge in der sie ankommen (zufällig) angeheftet.
Meine Vermutung ist, dass das relativ leicht machbar ist. Ich finde dazu allerdings nichts.
Ich hoffe es findet sich jemand, der mir helfen kann.

Code: Alles auswählen


import time
import threading
import random
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation


def temperature_to_txt():
    file = open("Temperatur3.txt", "w")
    file.close()
    while True:
        zufalls_temp = random.randint(25, 30)
        print(zufalls_temp)
        aktuelle_zeit = time.strftime("%H:%M:%S")


        with open('Temperatur3.txt') as f:
            list_length = (sum(1 for _ in f))

        if list_length <= 5:
            file = open("Temperatur3.txt", "a")
            file.write(str(aktuelle_zeit) + "," + str(zufalls_temp) + "\n")
            file.close()

        elif list_length > 5:
            file = open("Temperatur3.txt", "r")
            lines = file.readlines()
            lines.pop(0)
            file = open("Temperatur3.txt", "w")
            file.write(str(lines[0])+str(lines[2])+str(lines[3])+str(lines[4]))
            file.write(str(aktuelle_zeit) + "," + str(zufalls_temp) + "\n")
            file.close()

        time.sleep(1)


def animate(i):
    graph_data = open("Temperatur3.txt", "r").read()
    lines = graph_data.split("\n")
    xs = []
    ys = []
    for line in lines:
        if len(line) > 1:
            x, y = line.split(",")
            xs.append(x)
            ys.append(y)
    plt.cla()
    plt.plot(xs, ys)
    plt.tight_layout()


def main():

    threading.Thread(
        target = temperature_to_txt, daemon= True
    ).start()

    plt.style.use("fivethirtyeight")
    ani = FuncAnimation(plt.gcf(), animate, interval = 1000)


    plt.show()

if __name__ == "__main__":
    main()




MfG

Re: Matplotlib y_achse bei live Graph festsetzen

Verfasst: Dienstag 2. Juni 2020, 13:42
von Sirius3
Dateien, die man öffnet, sollte man auch wieder schließen. Am besten benutzt man dazu das with-Statement.
Wenn Du eh die ganze Datei liest, um die Anzahl der Zeilen herauszu bekommen, kannst Du Dir auch gleich den Inhalt merken.
Beim Lesen und Schreiben immer ein Encoding angeben. Strings stückelt man nicht mit + zusammen, sondern benutzt Format-Strings.
Benutzt keine Abkürzungen.

Code: Alles auswählen

TEMPERATURE_FILENAME = "Temperatur3.txt"

def temperature_to_txt():
    with open(TEMPERATURE_FILENAME, "w", encoding="ASCII"):
        pass
    while True:
        zufalls_temperatur = random.randint(25, 30)
        with open(TEMPERATURE_FILENAME, encoding="ASCII") as input:
            lines = input.readlines()
        lines.append(f"{DateTime.now():%H%M:%S},{zufalls_temperatur}\n")
        lines = lines[-5:]
        with open(TEMPERATURE_FILENAME, "w", encoding="ASCII") as output:
            output.writelines(lines)
        time.sleep(1)
Da Du sowieso nur eine Schleife hast, die schreibt, brauchst Du auch nicht die Dateien immer wieder zu lesen.

Code: Alles auswählen

def temperature_to_txt():
    lines = []
    while True:
        zufalls_temperatur = random.randint(25, 30)
        print(zufalls_temp)
        lines.append(f"{DateTime.now():%H%M:%S},{zufalls_temperatur}\n")
        lines = lines[-5:]
        with open(TEMPERATURE_FILENAME, "w", encoding="ASCII") as output:
            output.writelines(lines)
        time.sleep(1)
Und eigentlich brauchst Du die Daten gar nicht in eine Datei schreiben, sondern kannst sie auch direkt übergeben:

Code: Alles auswählen

import time
import threading
import random
import matplotlib.pyplot as plt
from datetime import datetime as DateTime
from matplotlib.animation import FuncAnimation
from collections import deque

def temperature_to_queue(queue):
    while True:
        zufalls_temperatur = random.randint(25, 30)
        queue.append((DateTime.now(), zufalls_temperatur))
        time.sleep(1)

def animate(frame, ax, queue):
    ax.cla()
    return ax.plot(*zip(*queue))

def main():
    queue = deque([],maxlen=5)
    threading.Thread(
        target=temperature_to_queue, args=(queue,), daemon=True
    ).start()
    fig, ax = plt.subplots()
    ani = FuncAnimation(fig, animate, fargs=(ax, queue,), interval=1000)
    plt.show()

if __name__ == "__main__":
    main()

Re: Matplotlib y_achse bei live Graph festsetzen

Verfasst: Dienstag 2. Juni 2020, 20:10
von Finn_h
Das ist natürlich sehr schlank. Danke dir. Das hilft mir sehr weiter!

Nur mal aus Interesse, wodran lag das bei meinem Code, dass die y-Achse sich so seltsam verhält und wäre mein Code noch zu retten?