Closed Doid-Reyewliz closed 3 years ago
Hi Doid-Reyewliz, thanks for trying pygubu.
I think the question refers to how to use pygubu, tkinter and matplotlib together.
I don't use the matplotlib library much but I had a little time to play with your code and this is what came up. It may serve as a starting point for you (You should investigate how to make better animations with matplotlib).
Greetings. Alejandro A.
File: issue220.py
import os
import tkinter as tk
import pygubu
import matplotlib
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg,
NavigationToolbar2Tk)
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
from math import sin, cos, radians
class Cannon:
def __init__(self, x0, y0, v, angle):
self.x = x0
self.y = y0
self.vx = v*cos(radians(angle))
self.vy = v*sin(radians(angle))
self.ax = 0
self.ay = -9.8
self.time = 0
self.xarr = [self.x]
self.yarr = [self.y]
def updateVx(self, dt):
self.vx = self.vx + self.ax*dt
return self.vx
def updateVy(self, dt):
self.vy = self.vy + self.ay*dt
return self.vy
def updateX(self, dt):
self.x = self.x + 0.5*(self.vx + self.updateVx(dt))*dt
return self.x
def updateY(self, dt):
self.y = self.y + 0.5*(self.vy + self.updateVy(dt))*dt
return self.y
def step(self, dt):
self.xarr.append(self.updateX(dt))
self.yarr.append(self.updateY(dt))
self.time = self.time + dt
def makeShoot(x0, y0, velocity, angle):
cannon = Cannon(x0, y0, velocity, angle)
dt = 0.05 # time step
t = 0
cannon.step(dt)
while cannon.y >= 0:
cannon.step(dt)
t = t + dt
return (cannon.xarr, cannon.yarr)
PROJECT_PATH = os.path.dirname(__file__)
PROJECT_UI = os.path.join(PROJECT_PATH, "issue220.ui")
class Issue220App:
def __init__(self):
self.builder = builder = pygubu.Builder()
builder.add_resource_path(PROJECT_PATH)
builder.add_from_file(PROJECT_UI)
self.mainwindow = builder.get_object('mainwindow')
# Container for the matplotlib canvas and toolbar classes
fcontainer = builder.get_object('fplot')
# Setup matplotlib canvas
self.figure = fig = Figure(figsize=(5, 4), dpi=100)
self.canvas = canvas = FigureCanvasTkAgg(fig, master=fcontainer)
canvas.draw()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
# Setup matplotlib toolbar (optional)
#self.toolbar = NavigationToolbar2Tk(canvas, fcontainer, pack_toolbar=True)
#self.toolbar.update()
builder.connect_callbacks(self)
def on_draw_click(self):
self.figure.clear()
x0 = 0
y0 = 60
velocity = 25
x45, y45 = makeShoot(x0, y0, velocity, 45)
x30, y30 = makeShoot(x0, y0, velocity, 30)
x60, y60 = makeShoot(x0, y0, velocity, 60)
sp = self.figure.add_subplot(111)
sp.plot(x45, y45, 'bo-', x30, y30, 'ro-', x60, y60, 'ko-', [0, 12], [0, 0], 'k-')
#print(x45)
#sp.plot(x45, x45)
sp.legend(['45 deg shoot', '30 deg shoot', '60 deg shoot'])
sp.set_xlabel('X coordinate (m)')
sp.set_ylabel('Y coordinate (m)')
self.canvas.draw()
def on_animate_click(self):
self.anim_step = 5
velocity = 25
self.dt = 0.1
self.time = 0
self.cannons = [
Cannon(0, 0, velocity, 45),
Cannon(0, 0, velocity, 30),
Cannon(0, 0, velocity, 60)
]
self.mainwindow.after(self.anim_step, self.anim)
def anim(self):
self.figure.clear()
ax = self.figure.add_subplot(111)
continue_anim = False
for c in self.cannons:
if c.y >= 0:
c.step(self.dt)
print(c.x, c.y)
continue_anim = True
ax.plot(c.xarr, c.yarr)
ax.legend(['45 deg shoot', '30 deg shoot', '60 deg shoot'])
ax.set_xlabel('X coordinate (m)')
ax.set_ylabel('Y coordinate (m)')
self.canvas.draw()
if continue_anim:
self.mainwindow.after(self.anim_step, self.anim)
def run(self):
self.mainwindow.mainloop()
if __name__ == '__main__':
app = Issue220App()
app.run()
File: issue220.ui
<?xml version='1.0' encoding='utf-8'?>
<interface version="1.0">
<object class="tk.Toplevel" id="mainwindow">
<property name="geometry">640x480</property>
<property name="height">200</property>
<property name="resizable">both</property>
<property name="title" translatable="yes">My App</property>
<property name="width">200</property>
<child>
<object class="ttk.Frame" id="fmain">
<property name="height">200</property>
<property name="padding">2</property>
<property name="width">200</property>
<layout manager="pack">
<property name="expand">true</property>
<property name="fill">both</property>
<property name="propagate">True</property>
<property name="side">top</property>
</layout>
<child>
<object class="ttk.Frame" id="ftop">
<property name="height">200</property>
<property name="padding">2</property>
<property name="width">200</property>
<layout manager="pack">
<property name="fill">x</property>
<property name="propagate">True</property>
<property name="side">top</property>
</layout>
<child>
<object class="ttk.Label" id="label_1">
<property name="font">{Helvetica} 16 {bold}</property>
<property name="text" translatable="yes">Cannon graph</property>
<layout manager="pack">
<property name="padx">0 20</property>
<property name="propagate">True</property>
<property name="side">left</property>
</layout>
</object>
</child>
<child>
<object class="ttk.Button" id="button_1">
<property name="command">on_draw_click</property>
<property name="text" translatable="yes">Draw</property>
<layout manager="pack">
<property name="propagate">True</property>
<property name="side">left</property>
</layout>
</object>
</child>
<child>
<object class="ttk.Button" id="button_1_2">
<property name="command">on_animate_click</property>
<property name="text" translatable="yes">Animate</property>
<layout manager="pack">
<property name="padx">10 0</property>
<property name="propagate">True</property>
<property name="side">left</property>
</layout>
</object>
</child>
</object>
</child>
<child>
<object class="ttk.Frame" id="fplot">
<property name="height">200</property>
<property name="width">200</property>
<layout manager="pack">
<property name="expand">true</property>
<property name="fill">both</property>
<property name="propagate">True</property>
<property name="side">top</property>
</layout>
</object>
</child>
</object>
</child>
</object>
</interface>
Thanks you very much
@alejandroautalan I have a question. I need the y0 and velocity values to be taken from Entry. How to make the values come from Entry. I created a record, but how do I write a command now?
@alejandroautalan I have a question. I need the y0 and velocity values to be taken from Entry. How to make the values come from Entry. I created a record, but how do I write a command now?
See issue #221 with the response.
Regards! Alejandro A.
Hello. I'm trying to display an animated graph into a canvas and also trying to put this into new frame in application. I want this graph will displayed in application
from math import sin, cos, radians from matplotlib import pyplot as plt
class Cannon:
def makeShoot(x0, y0, velocity, angle):
def main(): x0 = 0 y0 = 60 velocity = 25
if name == 'main': main()