05 - Ambientes Interactivos Con Python
05 - Ambientes Interactivos Con Python
Problema 1
En un circuito RLC serie con una fuente de voltaje AC, la amplitud de la corriente I esta
dada por:
vm
I =
2 2
√R + (ωd L − 1/(ωd C))
In [2]: R = 80
C = 18e-6
L = 260e-3
vm = 10
fd = np.arange(10, 10000)
wd = 2 * np.pi * fd
plt.figure(figsize=(8, 6))
plt.semilogx(fd, I, color='magenta')
plt.title("Corriente en un circuito RLC Serie")
plt.xlabel("Frecuencia [Hz]")
plt.ylabel("Amplitud")
plt.grid(linestyle="dashed", which='both')
plt.show()
Problema 2
La distribución de velocidad, N (v), de las moléculas de un gas puede ser modelado por
la ley de distribución de velocidad de Maxwell:
2
m −mv
3/2 2
N (v) = 4π( ) v e 2kT
2πkT
In [3]: k = 1.38e-23
m = 5.3e-26
v = np.linspace(0, 1200, 100)
plt.figure(figsize=(8, 6))
T = 80
N = (4 * np.pi) * ((m / (2 * np.pi * k * T))**(3/2)) * (v**2 * np.exp((-m * v**2
plt.plot(v, N, label="T=80K")
T = 300
fig, ax = plt.subplots()
ax.plot(meses, equipo1, marker='o', label='Equipo 1')
ax.plot(meses, equipo2, marker='s', label='Equipo 2')
ax.set_title("Márgenes de Utilidad - 2023")
ax.set_xlabel("Meses")
ax.set_ylabel("Utilidad [USD]")
ax.legend(loc='lower right')
ax.grid()
plt.show()
Out[5]:
Así también, podemos tener un grado de personalización del gráfico completo ya que se
pueden modificar todos los objetos gráficos. Por ejemplo, los spines (las líneas que
enmarcan un Axes) solo se pueden editar por medio de setters sobre un objeto Axes:
In [6]: ax.set_facecolor('lightgray')
ax.spines.top.set_visible(False)
ax.spines.right.set_visible(False)
ax.grid(color='white')
fig
Out[6]:
Tambien podemos definir varios Axes sobre una misma figura asignando las propiedades
al método plt.subplots():
plt.tight_layout()
plt.show()
plt.tight_layout()
plt.show()
Así tambien, por ejemplo, se pueden obtener ciertos resultados gráficos utilizando esta
metodología que no se podrían obtener por medio de la forma "implícita":
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Tk Animation App")
self.WIDTH = 300
self.HEIGHT = 400
self.SIZE = 15
if self.x < xmouse < (self.x + self.SIZE) and self.y < ymouse < (self.y
self.canvas.delete(self.ball)
self.x, self.y = randrange(0, self.WIDTH), randrange(0, self.HEIGHT)
self.ball = self.canvas.create_oval(self.x, self.y,
self.x + self.SIZE, self.y + sel
fill='red')
App().mainloop()
class App(ctk.CTk):
def __init__(self):
super().__init__()
self.title("Clock")
self.resizable(0, 0)
ctk.set_appearance_mode('dark')
FONT = {'font': ('Digital-7 Mono', 50, 'bold'), 'text_color': ('white',
self.update_clock()
def update_clock(self):
self.lblHora.configure(text=f"{datetime.now():%H:%M:%S}")
self.after(500, self.update_clock)
App().mainloop()
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("CPU Data")
self.resizable(0, 0)
self.var_usage_CPU = tk.DoubleVar()
self.var_battery_percent = tk.IntVar(value=50)
frm = tk.Frame(self)
frm.pack(padx=10, pady=10)
self.read_psutil_data()
def read_psutil_data(self):
self.var_usage_CPU.set(psutil.cpu_percent())
self.var_battery_percent.set(psutil.sensors_battery().percent)
self.lblCPU_Usage.config(text=f"CPU Usage: {self.var_usage_CPU.get()}%")
self.lblBAT_Usage.config(text=f"Battery Available: {self.var_battery_per
if psutil.sensors_battery().power_plugged:
self.lblBAT_Usage.config(fg='black');
else:
self.lblBAT_Usage.config(fg='red');
self.after(1000, self.read_psutil_data)
app = App().mainloop()
matplotlib en tkinter
Se puede insertar un gráfico de matplotlib en una interface tkinter, utilizando el objeto
FigureCanvasTkAgg . Esto permite crear una figura que recibirá el Figure de
matplotlib y lo convertirá en un widget tipo Canvas .
Posteriormente, este canvas de puede actualizar con el método draw . Los cambios en la
gráfica se hacen directamente sobre la información de los arreglos a plotear.
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Onda Senoidal")
frm = tk.Frame(self)
frm.pack(padx=10, pady=10)
self.freq = tk.IntVar(value=1)
self.amp = tk.DoubleVar(value=6.0)
self.Y_LIMIT = 12
self.FREQ_MAX = 10
frm1 = tk.Frame(frm)
frm2 = tk.Frame(frm)
frm1.pack(padx=10, pady=10)
frm2.pack(padx=10, pady=10)
def amp_down(self):
if self.amp.get() > 0:
self.amp.set(self.amp.get() - 0.1)
self.update_graph()
def amp_up(self):
if self.amp.get() < self.Y_LIMIT:
self.amp.set(self.amp.get() + 0.1)
self.update_graph()
def freq_down(self):
if self.freq.get() > 1:
self.freq.set(self.freq.get() - 1)
self.update_graph()
def freq_up(self):
def update_graph(self):
self.line.set_ydata(self.amp.get() * np.sin(2 * np.pi * self.freq.get()
self.ax.set_title(f"Onda Senoidal @ {self.freq.get():.1f}Hz")
self.graph.draw()
app = App().mainloop()
Los valores gestionados por estos widgets ( widget.value ) se pueden asociar como
parametros de una función con interact :
w1 = IntSlider(description="IntSlider")
w2 = FloatSlider(description="FloatSlider")
w3 = BoundedIntText(description="BoundedIntText")
w4 = BoundedFloatText(description="BoundedFloatText", step=0.5)
w5 = Combobox(description="Combobox", options=['1', '2', '3'])
w6 = Dropdown(description="Dropdown", options=[1, 2, 3])
w7 = RadioButtons(description="RadioButtons", options=[1, 2, 3])
w8 = Checkbox(description="Checkbox")
w9 = Text(description="Text")
w10 = Button(description="Button")
gui = VBox([w1, w2, w3, w4, w5, w6, w7, w8, w9, w10])
display(gui)
Eventos
Los widgets manejan eventos definidos como métodos del objeto widget. Por ejemplo,
en el caso del Button , el evento a consutar en on_click :
def print_message(event):
print(txt.value)
but.on_click(print_message)
Otros widgets sportan el método observe que les permite ser observados
constantemente y llama a un evento en cuando haya sucedido un cambio con el widget.
def print_message(event):
txt.value = str(sld.value)
sld.observe(print_message)
Sin embargo, la mejora manera de tomar control sobre estas acciones es a través de
interactive , que retorna un VBox que se puede instanciar como un objeto para
luego mostrarlo con display :
HBox(children=(VBox(children=(HBox(children=(FloatSlider(value=1.0, description
='Radio:', max=12.0, min=1.0), …