How do I update a smith chart from pySmithPlot as data is read from a serial port in Tkinter?

-1

I'm making a GUI in Tkinter with a page that has 2 smith charts. The GUI is for a device that interacts through a serial port. The GUI has multiple pages. I would like the smith charts to update every time data becomes available from the device. This frequency can change depending on the baudrate the user configures the device with. I'm using pySmithPlot to plot the smith charts.

I've technically accomplished this, but have not produced the results I need. Reading device from the data and updating the graphs are in a separate thread from the main gui. When I run the thread with code snippet (1), the thread runs as fast as the device can read and send back data. But, for some reason, the plots only update on the GUI when I resize the window.

However, when I run with code snippet (2), the graphs update after every function call, but the thread runs significantly slower. From what I've read online, I need to create new widgets in order for the plots to appear. If you don't destroy the old widget, the program just places the new one on top of the old one. I've tried just updating the widgets without destroying the old ones, but the user needs to be able to resize and interact with the application and not destroying old widgets makes the application much less responsive (literally because the app has to resize however many widgets as the thread has been called). I've also looked into animation, but there are no examples for pySmithPlot, and I've found no way to use any kind of set_data method (python says none exists for pysmithplot). Animating then boils down to clearing the graph and redrawing everything with the new data, which is what the above code does anyway.

Also, for some reason, code snippet (3) actually produces the results I need (clears the graph and plots smith charts in gui without having to destroy or create any new widgets and with no significant reduction to thread time) but causes the program to close after 2 thread calls with the following error message: Process finished with exit code -1073741819 (0xC0000005)

Any help anyone could give would be greatly appreciated. As a side note, this process needs to happen even if the user resizes the window. Right now, if the user resizes the window while the function from the thread is running, it stops or delays it and I get back errors from the device. If anyone has any input for this it would be great, though this I think I can figure out on my own (bind the event to a function that stops the thread, and bind the event to a function that resizes it). If anyone has any better solutions please let me know.

The code snippets (1-3) are from the update function in my thread. I will attach part of the populate function below as code snippet (4), which sets up the graphs for the first time, and shows you where self.smith1 and self.smith2 come from.

(1)    
    self.smith1data.append(complex(zingraph))
    self.smith2data.append(complex(zloadgraph))
    self.ax1.clear()
    self.ax2.clear()
    self.ax1.plot(self.smith1data, datatype=SmithAxes.Z_PARAMETER)
    self.ax2.plot(self.smith2data, datatype=SmithAxes.Z_PARAMETER)


(2)   
    self.smith1data.append(complex(zingraph))
    self.smith2data.append(complex(zloadgraph))
    self.ax1.clear()
    self.ax2.clear()
    self.ax1.plot(self.smith1data, datatype=SmithAxes.Z_PARAMETER)
    self.ax2.plot(self.smith2data, datatype=SmithAxes.Z_PARAMETER)
    self.smith1 = FigureCanvasTkAgg(self.f, self.smithspace1)
    self.smith2 = FigureCanvasTkAgg(self.g, self.smithspace2)
    self.smith1temp = self.smith1widget
    self.smith2temp = self.smith2widget
    self.smith1widget = self.smith1.get_tk_widget()
    self.smith2widget = self.smith2.get_tk_widget()
    self.smith1widget.place(relwidth = 1, relheight = 1)
    self.smith2widget.place(relwidth = 1, relheight = 1)
    self.smith1temp.destroy()
    self.smith2temp.destroy()     

(3)   
    self.smith1data.append(complex(zingraph))
    self.smith2data.append(complex(zloadgraph))
    self.ax1.clear()
    self.ax2.clear()
    self.ax1.plot(self.smith1data, datatype=SmithAxes.Z_PARAMETER)
    self.ax2.plot(self.smith2data, datatype=SmithAxes.Z_PARAMETER)
    self.smith1.draw()
    self.smith2.draw()

(4)
    self.f = pyplot.Figure(figsize=(5, 5), dpi=100)
    self.ax1 = self.f.add_subplot(111, projection = 'smith', 
    grid_minor_enable = False, axes_normalize_label = False)
    self.ax1.plot([51.5 - 2.4j], datatype=SmithAxes.Z_PARAMETER)
    self.smith1data = []
    self.smith1data.append(51.5-2.4j)
    self.smith1 = FigureCanvasTkAgg(self.f, self.smithspace1)
    self.f.tight_layout()
    self.smith1widget = self.smith1.get_tk_widget()
    self.smith1widget.place(relx = 0, rely = 0, relwidth = 1, relheight = 
    1)
    self.g = pyplot.Figure(figsize=(5, 5), dpi=100)
    self.ax2 = self.g.add_subplot(111, projection = 'smith', 
    grid_minor_enable = False)
    self.ax2.plot([1.2 + 12.1j], datatype=SmithAxes.Z_PARAMETER)
    self.smith2data = [1.2+12.1j]
    self.smith2 = FigureCanvasTkAgg(self.g, self.smithspace2)
    self.g.tight_layout()
    self.smith2widget = self.smith2.get_tk_widget()
    self.smith2widget.place(relx = 0, rely = 0, relwidth = 1, relheight = 
    1)
python
plot
tkinter
asked on Stack Overflow Aug 6, 2019 by Shahrez Ahmad

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0