I’m trying to display a plot frame without data (for now) and change the xaxis scale with a variable while in a loop.
This program does not show the xaxis as 0 to 1, at least not long enough to see it while it flashes something. It waits 3 seconds and shows 0 to 3. The while(True) loop stops at 0 to 3 and hangs. Any suggestions?
```
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np
import time
def update(frame): # Define the animation function
ax.set_xlim(0, xscl) # Update the axis limits
return []
fig, ax = plt.subplots() # Create a figure and axes
xscl=1
ax.set_xlim(0, 1) # Set initial axis limits
ax.set_ylim(0, 1)
while(True):
ani = FuncAnimation(fig, update, frames=1, interval=3000, blit=True)
time.sleep(2)
xscl=xscl+2
plt.show()
```
I ran the original example using FuncAnimate. It keeps running indefinitely.
This is not at all what I am trying to do. I have a tkinter control panel with a blank plot display (like a digital oscilloscope). When I change a spinbox (x scale) from, say, 1v/div to 2v/div I want the xlim to change from 0 to 10 to 0 to 20.
When various settings are complete I will start an ADC that will fill the display one point at a time without changing the axis limits.
What should I be using? I will be controlling the timing that is not linear.
I am still interested in knowing why my above example does not work properly. The last plt.show() is what is hanging it. If I comment that out the While loop keeps running but I get:
Traceback (most recent call last):
File “C:\Users\bunge\AppData\Roaming\Python\Python310\site-packages\matplotlib\cbook.py”, line 361, in process
func(*args, **kwargs)
File “C:\Users\bunge\AppData\Roaming\Python\Python310\site-packages\matplotlib\animation.py”, line 938, in _stop
self._fig.canvas.mpl_disconnect(self._resize_id)
AttributeError: ‘FuncAnimation’ object has no attribute ‘_resize_id’
Obviously I don’t know what I’m doing.
The relevant code for the plot embedded in tkinter shown above is:
# Importing Necessary Libraries:
import tkinter as tk
from tkinter import * # Import the library tkinter
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg # , NavigationToolbar2Tk
import numpy as np
# Define Function. Creating the Tkinter Window and Plot Function:
def plot_data():
fig = Figure(figsize=(6, 4), dpi=100) # Create a Matplotlib Figure
ax = fig.add_subplot(111)
ax.set_xlim(0, xvalue) # Set limits for the axes
ax.set_ylim(0, 10)
ax.set_xlabel("X-axis") # Add labels to the axes
ax.set_ylabel("Y-axis")
ax.grid(True) # Enable the grid
# Plot the data
# ax.plot(x, y)
# Embed the Matplotlib plot into the Tkinter window
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.draw()
canvas.get_tk_widget().place(relx=0.5, rely=0.0, anchor="n")
plt.pause(0.1)
def getxval():
xval = input("Enter x value: ")
print ("xval is: ", xval)
# delete plot, call plot
xvalue=20
# Create the main Tkinter window
root = tk.Tk() # initialize tkinter & interpreter, root is widget container
root.geometry("800x800") # size of frame
plot_data() # call plot function above
getxval()
# Start the Tkinter event loop
root.mainloop()
```
If I comment out getxval() the program runs and draws the plot.
However, as shown, I get to enter a value but then the plot is not displayed and the program hangs.
I assume that xvalue is global and I need to declare it as such in any function that changes it in the main loop.
I assume that once the plot is drawn I need to delete and redraw it to change the axes limits? This will happen occasionally and the new value will come from the function that is called by the spinbox.
The next issue is going to be when I try to plot the data point by point without redrawing or changing the axes.
I need to do something like
```
import numpy as np
import matplotlib.pyplot as plt
plt.axis([0, 100, 0, 200]) # left, bottom, width, height
#1 plot.show()
for x in range(100):
y=x*2
plt.plot(x,y, 'ko')
plt.pause(0.1)
plt.show()
```
But I think this has the same problems as my above two programs. There is something I don't understand.
Edit: Everything between plt.axis..... and plt.show has to do with the
plot including the forloop. Placing plot.show() in the commented out
position shows the frame but not the plotted data. I never got this
from reading the tutorials. Maybe someone can point me to the explanation.
I am making progress but I would still like an explanation of the above.
The axis scales now change with the ‘switch’ (spinbox) settings. This is the relevant software:
def plot_data(xx):
# Create a Matplotlib Figure
fig = Figure(figsize=(6, 4), dpi=100)
ax = fig.add_subplot(111)
# Optionally, you can set limits for the axes to define the visible area
ax.set_xlim(0, xx)
ax.set_ylim(0, 10)
# Optionally, add labels to the axes
ax.set_xlabel("X-axis")
ax.set_ylabel("Y-axis")
# Set the major tick locator for the x-axis to have a maximum of 10 ticks
ax.xaxis.set_major_locator(MaxNLocator(nbins=10))
# Set the major tick locator for the y-axis to have a maximum of 10 ticks
ax.yaxis.set_major_locator(MaxNLocator(nbins=10))
ax.grid(True, which='major')
# Plot the data
# ax.plot(x, y)
# ax.set_title("Sine Wave Plot")
# Embed the Matplotlib plot into the Tkinter window
canvas = FigureCanvasTkAgg(fig, master=root)
canvas.draw()
canvas.get_tk_widget().place(relx=0.5, rely=0.0, anchor="n")
plt.pause(0.1)
# Add Matplotlib's navigation toolbar
#toolbar = NavigationToolbar2Tk(canvas, root)
#toolbar.update()
#canvas.get_tk_widget().grid(row=1)
```
This is the function that responds to a spinbox change.
It sends the scaling update (xscl) to plot_data(xx) above
```
# Setup input scaling
def xscaling_change():
xvalue = xscl = xscaling.get() # don't mess up xvalue
xcode = xscale_code[xvalue] # this is a 'key' byte that controls my hardware
xscl=xscl.replace(" V/div", "") # strip off the text
xscl=float(xscl)*10 # convert from string to a number
plot_data(xscl) # update the plot axis
xcode = xcode | 0x40 # OR in the channel ID for the hardware
print("X Scaling changed to:", xvalue) # these are just to confirm the software
print ("xscl = ", xscl)
print ("Decimal Code is: ", xcode)
print ("Hex Code is: ", hex(xcode))
Note: I am not using FuncAnimation.```
This project is an analog plotter emulator. It uses a PIC to send data to a RaspberryPi. Anyone interested contact me offline.
With minor changes it can be several projects.