Translate this matplotlib to kivy

46 views
Skip to first unread message

Christopher Logan

unread,
Apr 4, 2022, 9:03:38 PM4/4/22
to Kivy users support
Hi Folks, i'm looking into converting an existing application using Matplotlib v3.3.1+
i created a poc that contains the versions of plots i need on RasberryPi - the application as it is written works on Raspberry Pi already. can you help convert this into a Kivy App? I don't need the pan/zoom and matplotilb tools at the bottom - just the plots on the canvas above.

Here is the code that i have running on Rasberry Pi and that needs to be converted to Kivy:


import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

fig, ax = plt.subplots(6)
x = np.arange(0, 2*np.pi, 0.01)
print("len="+str(len(x))+" " +str(x))
dataLen = len(x)
line, = ax[0].plot(x, np.sin(x))
line1, = ax[1].plot(x, np.sin(x))
line2, = ax[2].plot(x, np.sin(x))
line3, = ax[3].plot(x, np.sin(x))
line4, = ax[4].plot(x, np.sin(x))
line5, = ax[5].plot(x, np.sin(x))
indx = 0

def createGap(data, currentIndx):
    gap = 15
    gapIndx=currentIndx+1
    for x in range(gap):
        if gapIndx+x < len(data):
            data[gapIndx+x] = np.nan

def animate(i):
    indx = i % dataLen
    newYData = line.get_ydata()
    print(str(i)+ " indx=" + str(indx) + " " + str(i/50) + " " +str(np.sin(x+i/50)))
    newYData[indx] = np.sin(x[indx] + i / 50)
    #line.set_ydata(np.sin(x + i / 50)) # update the data.
    createGap(newYData, indx)
    line.set_ydata(newYData)
    return line,

def animate1(i):
    line1.set_ydata(np.sin(x + i / 50)) # update the data.
    return line1,
def animate2(i):
    line2.set_ydata(np.sin(x + i / 50)) # update the data.
    return line2,
def animate3(i):
    line3.set_ydata(np.sin(x + i / 50)) # update the data.
    return line3,
def animate4(i):
    line4.set_ydata(np.sin(x + i / 50)) # update the data.
    return line4,
def animate5(i):
    line5.set_ydata(np.sin(x + i / 50)) # update the data.
    return line5,

ani = animation.FuncAnimation(fig, animate, interval=20, blit=True, save_count=50)
ani1 = animation.FuncAnimation( fig, animate1, interval=20, blit=True, save_count=50)
ani2 = animation.FuncAnimation( fig, animate2, interval=20, blit=True, save_count=50)
ani3 = animation.FuncAnimation( fig, animate3, interval=20, blit=True, save_count=50)
ani4 = animation.FuncAnimation( fig, animate4, interval=20, blit=True, save_count=50)
ani5 = animation.FuncAnimation( fig, animate5, interval=20, blit=True, save_count=50)

plt.show()

=====

Here is what I have so far but it just gets me to the static plot. does Kivy support the latest version of Matplotlib 3.5.1?


import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.app import App
from kivy.properties import ObjectProperty, StringProperty
from kivy.garden.matplotlib import FigureCanvasKivyAgg

fig, ax = plt.subplots(6)

x = np.arange(0, 2*np.pi, 0.01)
print("len="+str(len(x))+" " +str(x))
dataLen = len(x)
line, = ax[0].plot(x, np.sin(x))
line1, = ax[1].plot(x, np.sin(x))
line2, = ax[2].plot(x, np.sin(x))
line3, = ax[3].plot(x, np.sin(x))
line4, = ax[4].plot(x, np.sin(x))
line5, = ax[5].plot(x, np.sin(x))
indx = 0

def animate( i):
    indx = i % dataLen
    newYData = line.get_ydata()
    print(str(i)+ " indx=" + str(indx) + " " + str(i/50) + " "    +str(np.sin(x+i/50)))
    newYData[indx] = np.sin(x[indx] + i / 50)
    #line.set_ydata(np.sin(x + i / 50)) # update the data.
    self.createGap(newYData, indx)
    line.set_ydata(newYData)
    return line,

def animate1(i):
    line1.set_ydata(np.sin(x + i / 50)) # update the data.
    return line1,
def animate2(i):
    line2.set_ydata(np.sin(x + i / 50)) # update the data.
    return line2,
def animate3(i):
    line3.set_ydata(np.sin(x + i / 50)) # update the data.
    return line3,
def animate4(i):
    line4.set_ydata(np.sin(x + i / 50)) # update the data.
    return line4,
def animate5(i):
    line5.set_ydata(np.sin(x + i / 50)) # update the data.
    return line5,

ani = animation.FuncAnimation(fig, animate, interval=20, blit=True, save_count=50)
ani1 = animation.FuncAnimation(fig, animate1, interval=20, blit=True, save_count=50)
ani2 = animation.FuncAnimation(fig, animate2, interval=20, blit=True, save_count=50)
ani3 = animation.FuncAnimation(fig, animate3, interval=20, blit=True, save_count=50)
ani4 = animation.FuncAnimation( fig, animate4, interval=20, blit=True, save_count=50)
ani5 = animation.FuncAnimation(fig, animate5, interval=20, blit=True, save_count=50)

class vmc(FloatLayout):
    def __init__(self, info=None, **kwargs):
        super().__init__(**kwargs)
        label_wid = ObjectProperty()
        info = StringProperty()
        box = self.ids.box
        box.add_widget(FigureCanvasKivyAgg(plt.gcf()))

def createGap(self, data, currentIndx):
    gap = 15
    gapIndx=currentIndx+1
    for x in range(gap):
        if gapIndx+x < len(data):
            data[gapIndx+x] = np.nan

class vmcApp(App):
    def build(self):
        Builder.load_file('../ui/layouts/vmc.kv')
        return vmc()

# Main driver if this module is called like a script
# Currently just supports VCM
if __name__ == "__main__":
    vmcApp().run()


Thank you
-Christopher
Reply all
Reply to author
Forward
0 new messages