i am developing a weather monitoring program and i am stuck at a problem. the problem is when the array that contains the labels for the x axis exceeds the lenght of 50 the graph starts to break. and i need to set the x values to a custom array because it contains the exact time when was the measurmet executed
I would be happy if somebody could hep me solve the problem.
my code:
#made by danoo
import tkinter as tk
from tkinter import ttk
import threading
from random import randint
from time import sleep, time
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import numpy as np
def create_graph(root, height0, height1, width, gridX, gridY):
fig, ax = plt.subplots(figsize=(10, 3))
ax.set_ylim(height0, height1)
x = range(width)
y = [0] * width
line, = ax.plot(x, y)
# Create a frame for the graph
graph_frame = ttk.Frame(root)
graph_frame.place(x=gridX, y=gridY)
# Add the graph to the frame
canvas = FigureCanvasTkAgg(fig, master=graph_frame)
canvas.get_tk_widget().pack(fill=tk.BOTH, expand=tk.YES)
return line, canvas
def update_graph(line, data, canvas, width, x_values, height1, height0):
if height1 != 0:
line.axes.set_ylim([height0, height1])
y = list(data[-width:])
x = range(len(y))
line.set_data(x, y)
line.axes.relim()
line.axes.autoscale_view(False, True, True)
line.axes.set_xlim([0, len(y)])
xses = list(x_values[-width:])
# Set x-tick labels to display every 10th value
x_labels = [str(x_val) if x_val % 10 == 0 else '' for x_val in xses]
line.axes.set_xticks(xses)
line.axes.set_xticklabels(x_labels)
canvas.draw()
def communication(label, line, canvas):
m = []
x = []
i = 0
while True:
sleep(0.2)
recrived = randint(0,100)
m.append(recrived)
x.append(i)
i+=1
update_graph(line, m, canvas, 50, x, 100, 0)#might be bug !!!!!!!!!!
def main():
root = tk.Tk()
root.geometry("1024x600")
line, canvas = create_graph(root,10,40,50, 0 , 280)
comm_thread = threading.Thread(target=communication, args=(0,line, canvas))
comm_thread.start()
root.mainloop()
comm_thread.join()
if __name__ == "__main__":
main()
bassicly what this program does it cretes a graph and puts it onto the window. then the communication thread updates the graph. and in the update_graph function it gets the last 50 values from the data and the time arrays then it draws the data on the graph and gets every 10 value from the time array and and displays it to the x axis of the graph. and when the leght of time exceeds 50 the graph breaks. the problem is i think in the update_graph function but idk what.
y
values, then of course you must also take the last 50 x
values.y = list(data[-width:]) -> y = data[-width:]
x = range(len(y)) -> x = x_values[-width:]
A slice is a list anyway.
x
range on the chart must also take the last 50 values.line.axes.set_xlim([0, len(y)]) -> line.axes.set_xlim([x[0], x[-1]])
m
and x
lists in the communication
function.import tkinter as tk
from tkinter import ttk
import threading
from random import randint
from time import sleep, time
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import numpy as np
def create_graph(root, height0, height1, width, gridX, gridY):
fig, ax = plt.subplots(figsize=(10, 3))
ax.set_ylim(height0, height1)
x = range(width)
y = [0] * width
line, = ax.plot(x, y)
# Create a frame for the graph
graph_frame = ttk.Frame(root)
graph_frame.place(x=gridX, y=gridY)
# Add the graph to the frame
canvas = FigureCanvasTkAgg(fig, master=graph_frame)
canvas.get_tk_widget().pack(fill=tk.BOTH, expand=tk.YES)
return line, canvas
def update_graph(line, y, canvas, x, height1, height0):
if height1 != 0:
line.axes.set_ylim([height0, height1])
line.set_data(x, y)
line.axes.set_xlim([x[0], x[-1]])
# Set x-tick labels to display every 10th value
x_labels = [str(x_val) if x_val % 10 == 0 else '' for x_val in x]
line.axes.set_xticks(x)
line.axes.set_xticklabels(x_labels)
canvas.draw()
def communication(label, line, canvas, width):
m = []
x = []
i = 0
while True:
sleep(0.2)
recrived = randint(0, 100)
m.append(recrived)
x.append(i)
print(m, x)
i += 1
m = m[-width:]
x = x[-width:]
update_graph(line, m, canvas, x, 100, 0) #
def main():
root = tk.Tk()
root.geometry("1024x600")
line, canvas = create_graph(root, 10, 40, 50, 0, 280)
comm_thread = threading.Thread(target=communication, args=(0, line, canvas, 50))
comm_thread.start()
root.mainloop()
comm_thread.join()
if __name__ == "__main__":
main()
I think that we can do without threads by replacing the loop while
and the sleep(0.2)
with the after
method.