25 jun. 2011

Tutorial de PyQt. Parte 3

Continuando con los tutoriales de Python+Qt.

Esta vez se explicara una aplicación que maneje varios widgets, una entrada de datos para capturar el nombre de una persona, un comboBox que maneja una lista de ciudades, se muestra el botón aceptar que al darle clip muestra la información escrita y seleccionada; y el botón salir que al darle clip se sale del programa, también se definio que al darle cerrar a la ventana abra una ventana de dialogo que confirma la salida de la aplicación y que la aplicación tenga una imagen como icono en su ventana.

La documentación de referencia de las clases de PyQt lo pueden revisar en este enlace.

El código del programa  se muestra a continuación:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
     
#Se importa el modulo sys
import sys 
#De PyQt4 importar QtGui y QtCore
from PyQt4 import QtGui, QtCore


#Se crea la clase App que hereda de la clase QWidget.


class App(QtGui.QWidget):
    def __init__(self, parent=None):
       QtGui.QWidget.__init__(self, parent)
       #Se define el tamano de la ventana
       self.setGeometry(400, 400, 250, 150)
        #Se le coloca un titulo a la ventana y se asocia un icono. 
       self.setWindowTitle('Programa de prueba') 
       self.setWindowIcon(QtGui.QIcon('./openlogo-50.png'))
       
       #Se define los widgets dentro de la ventana
       #Etiqueta nombre
       self.nombre = QtGui.QLabel('Nombre: ')
       #Entrada de datos del nombre
       self.nombreEdit = QtGui.QLineEdit()
       #Etiqueta ciudad.
       self.ciudadEtiqueta = QtGui.QLabel("Ciudad:")
       #Se define el comboBox con las ciudades
       self.combo = QtGui.QComboBox(self)
       ciudades = ["Valencia","Maracay","Barquisimeto","Merida","Caracas"]
       
       for ciudad in ciudades:
 self.combo.addItem(ciudad)
 


 
       #Se define la etiqueta resultado
       #con campo de nombre y ciudad y 2
       #etiquetas donde se mostraran los resultados.
       self.resultado = QtGui.QLabel("Resultados: ")
       self.resultadoNombre = QtGui.QLabel("")
       self.resultadoCiudad = QtGui.QLabel("")
       self.etiquetaNombre = QtGui.QLabel("Info nombre:")
       self.etiquetaCiudad = QtGui.QLabel("Info Ciudad:")
       
       #Se define el boton para salir
       quit = QtGui.QPushButton('Salir', self)
       #Se define el boton aceptar
       okButton = QtGui.QPushButton("Aceptar",self)


       #Se define como empaquetar los widgets.
       #En este caso se usa grilla.
       #Se crea la instancia
       grid = QtGui.QGridLayout()
       grid.setSpacing(10)
       #Se agrupan los widgets pasando el
       #objeto luego el orden en vertical, el orden en
       #horizontal.
       grid.addWidget(self.nombre, 1, 0)
       grid.addWidget(self.nombreEdit, 1, 1)
       grid.addWidget(self.ciudadEtiqueta,2,0)
       grid.addWidget(self.combo,2,1)
       grid.addWidget(self.resultado,3,0)
       grid.addWidget(self.etiquetaNombre,4,0)
       grid.addWidget(self.resultadoNombre,4,1)
       grid.addWidget(self.etiquetaCiudad,5,0)
       grid.addWidget(self.resultadoCiudad,5,1)
       grid.addWidget(okButton, 6, 0)
       grid.addWidget(quit, 6, 1)
       


       #Se define el layout pasando la grilla
       self.setLayout(grid)

       
       #Se asocian las segnales del boton salir y aceptar
       #Se conecta el boton quit, con la segnal pasandole  el evento clicked, y se 
      #llama a qApp. en el boton aceptar se llama a buttonClicked.
       self.connect(quit, QtCore.SIGNAL('clicked()'),QtGui.qApp, QtCore.SLOT('quit()'))
       self.connect(okButton, QtCore.SIGNAL('clicked()'), self.buttonClicked)
    
    
    def buttonClicked(self):
 """Metodo del boton aceptar que captura
 la informacion del campo nombre y del comboBox ciudad
 y la muestra en 2 etiquetas como resultado
 """
 #Se captura la entrada de datos del nombre y se le pasa
 #a la etiqueta resultadoNombre
        self.resultadoNombre.setText(self.nombreEdit.text())
 #Se captura la seleccion del combo y se le pasa a la
 #etiqueta resultadoCiudad.
 self.resultadoCiudad.setText(self.combo.currentText())
        
    
    def closeEvent(self, event):
 """Evento que permite abrir una
 ventana de dialogo para confirmar la salida del programa
 """
 #Se genera la respuesta de la confirmacion de salir
        reply = QtGui.QMessageBox.question(self, 'Mensaje',
            "Seguro que desea salir?", QtGui.QMessageBox.Yes | 
            QtGui.QMessageBox.No, QtGui.QMessageBox.No)


        #Si se selecciona Si se acepta el evento, si se selecciona
 #no se ignora el evento
 if reply == QtGui.QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()
    
    


#Se ejecuta el programa principal
if __name__ == "__main__":    
   #Se instancia la clase QApplication    
   app = QtGui.QApplication(sys.argv)    
   #Se instancia el objeto QuitButton    
   qb = App()    
   #Se muestra la aplicacion    
   qb.show()    
   #Se sale de la aplicacion    
   sys.exit(app.exec_())
  
La figura muestra la venta de la aplicación al iniciarse:

Se escribe el nombre y se selecciona la ciudad y se le da clip al botón aceptar:

Se muestra el resultado luego de darle clip al botón aceptar:

Se le da clip para cerrar ventana:

Y pregunta si desea confirmar salir de la aplicación:

19 jun. 2011

Qtadb programa para controlar un celular Android desde el PC

En la página de elandroidlibre.com publicaron un artículo donde hablan del programa QtADB el cual permite manejar el sistema de archivos del celular, ver la lista de paquetes instalado, realizar capturas de pantalla, ejecutar la consola del celular, recovery y otras opciones. El enlace de el androidelibre.com lo tienen acá.

Es necesario tener instalado el SDK de Android, este se puede bajar en este enlace.

Es necesario instalar el paquete apk (qtadb.apk) en el celular y bajar el paquete QtADB para Linux en este caso para 32 bits lo pueden bajar en este enlace.

La página de qtadb se encuentra en el siguiente enlace.

El procedimiento para instalar el SDK de Android en Linux lo pueden seguir acá.

Al tener instalado el SDK de Android en Linux se conecta el celular y se inicia el servicio de adb:

ernesto@jewel:~/bin$ adb devices 
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached 
0403725B09015010 device

Pero para lograr esto es necesario habilitar el celular con conexión USB como Portal y Herramientas, la siguiente figura muestra la opción:


Para instalar el paquete apk en el celular se ejecuta el comando adb para la instalación de paquetes como se muestra:

ernesto@jewel:~/bin$adb install qtadb.apk 
44 KB/s (24316 bytes in 0.531s)
pkg: /data/local/tmp/qtadb.apk
Success

En la siguiente figura se muestra el programa instalado en el celular:

Al darle clip a QtADB se mostrará 2 botones uno para iniciar el servicio y otro para detenerlo como lo muestra la siguiente figura:


Se inicia el servicio y lo que queda es iniciar el QtADB para Linux.
Al iniciar la aplicación lo primero que se muestra es el administrador de archivos como lo muestra la siguiente figura:

Se puede listar las aplicaciones instaladas en el celular, actualizar aplicaciones, desintalarlas y realizar respaldos de las mismas.

Se puede ver información del celular como el operador de telefonía celular, modelo, número de serie, ROM y el espacio de las particiones.

Se pueden realizar capturas de pantalla en el celular.

Se puede ejecutar un shell del celular:

Se puede visualizar los logs del celular:

Por último también se puede visualizar los mensajes de texto:
Para que funcione revisar los mensajes es necesario activar y conectar el celular a la red wifi y en la aplicación activar wifi también.

En la siguiente figura se muestra los mensajes de texto almacenados en el celular:

16 jun. 2011

Programa para el envío de SMS desde Linux con Celular Android (conexión wifi y USB)

En el artículo de ejecución remota de script versión conectado por USB y la versión por wifi, se  explica  en el primer caso como enviar mensajes de texto y en el segundo como ejecutar una aplicación remotamente en el celular.

En este caso se fusionará ambos tipos de conexiones para enviar mensajes de texto tanto por USB como por wifi.

Para ello se creo un clase AndroidSMS donde se define los datos siguientes:

  • Tipo de conexión (wifi o usb)
  • Puerto (Puerto del servidor de SL4A que se activa en el celular)
  • Host (IP que tiene asignado el celular en la red wifi)

En los artículos mencionados anteriormente se explica como usar el comando adb del sdk de Android y la creación de variables de entorno para poder ejecutar remotamente scripts desde Linux al celular con Android. En este caso todo ese proceso se automatiza  en el script, pero es necesario para el caso USB ejecutar SL4A con la opción de privado y en el caso wifi con la opción de público. Además se tiene que verificar el número del puerto asignado en el servidor SL4A para pasarle como parámetro dichos datos al programa desde la línea de comandos.

A continuación se muestra el código del programa:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#Script que permite enviar mensaje de texto a un celular android desde Linux.
#Autor: Ernesto Crespo
#Correo:ecrespo@gmail.com
#Licencia: GPLv3
#Version:0.4
#Importando el modulo android,sys,re y getstatusoutput
import android,sys,re
from commands import getstatusoutput
class AndroidSMS:
    def __init__(self,conexion,puerto,host="192.168.0.100"):
        #Asignacion de la estructura de datos del Objeto
        self.__adb = "/home/ernesto/android-sdk-linux_x86/platform-tools/adb"
        self.__puerto = puerto
        self.__host = host
        self.__conexion = conexion
    
    def __ValidarNumero__(self,numero):
        """Valida si los numeros tienen 11 digitos y que sean
        de los proveedores movilnet, digitel y movistar
        """
        if len(numero) == 11 and ((re.search("041[2|4|6]\d\d\d\d\d\d\d",numero)) or (re.search("042[4|6]\d\d\d\d\d\d\d",numero))) :
            return 1
        else:
            return 0
    def __ConfigAndroid__(self):
        """__ConfigAndroid: Metodo que permite habilitar el funcionamiento
        del celular Android desde Linux tanto para wifi como para conexion USB
        """
        #Se apaga el servidor adb en el Linux
        getstatusoutput("%s kill-server" %self.__adb)
        #Se borra las variables de entorno AP_PORT y AP_HOST
        getstatusoutput("export AP_PORT=\"\"")
        getstatusoutput("export AP_HOST=\"\"")
        #Se inicia el servidor adb y se verifica que funciona correctamente
        r = getstatusoutput("%s devices" %self.__adb)
        if r[0] <> 0:
            print "Problemas con la configuracion del celular"
            sys.exit
        else:
            if self.__conexion == "usb":
                #Se verifica que el dispositivo aparece identificado
                if r[1].split("\n")[1] == "":
                    print "NO hay un celular conectado"
                    sys.exit
        #En este punto se tiene el dispositivo funcionando
        #Tanto por wifi como por usb.
        getstatusoutput("%s  forward tcp:9999 tcp:%s" %(self.__adb,self.__puerto))
        if self.__conexion == "wifi":
            #Se crean las variables de entorno AP_PORT y AP_HOST
            #para el caso de wifi
            getstatusoutput("export AP_PORT=%s" %self.__puerto)
            getstatusoutput("export AP_HOST=%s" %self.__host)
        elif self.__conexion == "usb":
            #Se crea la variable de entorno AP_PORT
            #para el caso conexion usb
            getstatusoutput("export AP_PORT=9999")
        print "Se configuro el celular sin problemas"
    def EnviarMensaje(self,numero,mensaje):
        """EnviarMensaje: Metodo que permite enviar un mensaje de texto
        pasando el numero y el mensaje
        Maneja ambos casos conexion USB o por red wifi.
        """
        if self.__ValidarNumero__(numero) == 0:
            print "Numero invalido"
            sys.exit
        #Creando la instancia droid del objeto Android
        self.__ConfigAndroid__()
        #Se crea la instancia del objeto Android dependiendo si es conexion
        #wifi se le pasa el host y el puerto
        #Si es conexion USB simplemente se crea la instancia
        if self.__conexion == "wifi":
            droid = android.Android((self.__host,self.__puerto))
        elif self.__conexion == "usb":
            droid = android.Android()
        #Enviando el mensaje de texto
        droid.smsSend(numero,mensaje)
        
    
if __name__ == '__main__':
    """Se capturan los valores de:
    *numero
    *mensaje
    *conexion
    *puerto
    *host
    """
    if len(sys.argv) == 6:
        numero = sys.argv[1]
        mensaje = sys.argv[2]
        conexion = sys.argv[3]
        puerto = sys.argv[4]
        host = sys.argv[5]
    elif len(sys.argv) == 5:
        numero = sys.argv[1]
        mensaje = sys.argv[2]
        conexion = sys.argv[3]
        puerto = sys.argv[4]
        host = ""
    else:
        print "Error: No se pasaron los parametros completos"
        sys.exit
    #Se crea la instancia de la clase AndroidSM pasando conexion,puerto y host
    androidsms = AndroidSMS(conexion,puerto,host)
    #Se envie el mensaje de texto
    androidsms.EnviarMensaje(numero,mensaje)

La ejecución del programa se muestra a continuación:
Se pasa primero el número de celular, luego el mensaje, luego el tipo de conexión (usb,wifi), luego el puerto y por último la IP si es el caso de wifi.

  • wifi: python mensaje4.py 0xxyyyzzww "Prueba3" wifi  47529 "192.168.0.100"
  • usb: python mensaje4.py 0xxyyyzzww "Prueba4" usb  43421
En la siguiente figura se muestra los mensajes recibidos en el celular:


10 jun. 2011

Generando una gráfica con PyQT y matplotlib (escala semilogaritmica). Parte 13

En este artículo se explicará como crear gráficas con escala semilogaritmitca.

La idea es graficar la función:
y = sin(pi*(x**(1/2)))

La gráfica muestra la figura de la función con escala semilogaritmica.

El código para generar la gráfica mostrada simplemente usando numpy y matplotlib es la siguiente:
#!/usr/bin/env python #Importar matplotlib import matplotlib as mpl #Definir el tamaño de la fuente mpl.rcParams['font.size'] = 10. #Importar pyplot import matplotlib.pyplot as plt #Importar numpy import numpy as np #Se crea el rango de valores de # 0 a 20 con saltos de 0.01 x = np.arange(0., 20, 0.01) #Se instancia la figura fig = plt.figure() #Se define  la grafica ax2 = fig.add_subplot(311) #Se genera el calculo de la funcion #con numpy y2 = np.sin(np.pi*(x**(1.0/2.0))) #Se define el eje X con escala #logaritmica ax2.semilogx(x, y2); #Se define el limite del eje X ax2.set_xlim([0, 20]); #Se define la grilla a la grafica ax2.grid(True) #se define una etiqueta en el eje Y ax2.set_ylabel('log X') #Se muestra la grafica plt.show()
En la siguiente figura se genera la gráfica utilizando PyQT, matplotlib y numpy:
A la gráfica se le agrego la barra de navegación y se le coloco un título a la ventana.

El código para crear la gráfica utilizando PyQT es el siguiente:
#!/usr/bin/env python
#Importar numpy 
import numpy as np
# Importar el objeto Figure de matplotlib
from matplotlib.figure import Figure

#Importar el Objeto FigureCanvas de Qt4Qgg,
#Se heredara desde QWidget.
from matplotlib.backends.backend_qt4agg \
  import FigureCanvasQTAgg as FigureCanvas

#Importar el widget de la barra de navegacion 
# import the NavigationToolbar Qt4Agg widget
from matplotlib.backends.backend_qt4agg \
  import NavigationToolbar2QTAgg as NavigationToolbar

#Importar QTGui de PyQt4.
from PyQt4 import QtGui

#Se crea la Clase Qt4MplCanvas heredando FigureCanvas
class Lienzo(FigureCanvas):
    
    def __init__(self, parent):
        # Se instancia el objeto figure
        self.fig = Figure()
        #Se define la grafica en coordenadas polares
        self.axes = self.fig.add_subplot(111)
        
        #Se define el rango de 0 a 20 con saltos de 0.01

        x = np.arange(0., 20, 0.01)
        #Se calcula los valores de la funcion.
        y2 = np.sin(np.pi*(x**(1.0/2.0)))
        #Se define el eje X como logaritmico
        #y se pasan los valores de x y y2.
        self.axes.semilogx(x, y2);
        #Se define el limite del eje X
        self.axes.set_xlim([0, 20]);
        #Se define una grilla
        self.axes.grid(True)
        #Se crea una etiqueta en el eje Y
        self.axes.set_ylabel('log X')
        
        # se inicializa FigureCanvas
        FigureCanvas.__init__(self, self.fig)
        # se define el widget padre
        self.setParent(parent)
        # se define el widget como expandible
        FigureCanvas.setSizePolicy(self,
                QtGui.QSizePolicy.Expanding,
                QtGui.QSizePolicy.Expanding)
        # se notifica al sistema de la actualizacion
        #de la politica
        FigureCanvas.updateGeometry(self)

#Se crea la clase Ventana que hereda QMainWindow
class Ventana(QtGui.QMainWindow):
    
    def __init__(self):
        
        #Inicializacion del widget QMainWindow
        QtGui.QMainWindow.__init__(self)
        # se define el titulo de la ventana
        self.setWindowTitle("Ventana PyQT con graficas a escala logaritmica")
        # instantiate a widget, it will be the main one
        # Se instancia el widget.
        self.main_widget = QtGui.QWidget(self)
        
        #Se crea una layout vbox
        vbl = QtGui.QVBoxLayout(self.main_widget)
        
        #Se instancia el Lienzo con la grafica de Matplotlib
        qmc = Lienzo(self.main_widget)
        # se instancia la barra de navegacion
        ntb = NavigationToolbar(qmc, self.main_widget)
        # se empaqueta el lienzo y 
        #la barra de navegacion en el vbox
        vbl.addWidget(qmc)
        vbl.addWidget(ntb)
        # se le asigna foco a la ventana
        self.main_widget.setFocus()
        #Se define el widget central
        self.setCentralWidget(self.main_widget)

if __name__ == '__main__':
    #Importar sys
    import sys
    #Importar QtGui de PyQt4
    from PyQt4 import QtGui
    #Se crea la aplicacion grafica
    qApp = QtGui.QApplication(sys.argv)
    # se instancia la ventana
    aw = Ventana()
    # se muestra el widget
    aw.show()
    #Se inicia el lazo principal de QT
    sys.exit(qApp.exec_())

8 jun. 2011

Generando una gráfica con PyQT y matplotlib (coordenadas polares). Parte 12

Continuando con los artículos sobre matplotlib y ahora usando PyQT, se explicará como crear gráficas con coordenadas polares.


La ecuación que se va a graficar es la siguiente:

r = 2* coseno(pi*t) siendo 0 <2

La gráfica se muestra en la siguiente figura:


El código para generar dicha gráfica es la siguiente:
#!/usr/bin/env python

#Importar pyplot
import matplotlib.pyplot as plt
#Importar numpy
import numpy as np

#Se crea el rango de valores angulares
theta = np.arange(0., 2., 0.005)*np.pi
#Se calcula el coseno del rango de valores angulares
r = 2*np.abs(np.cos(theta))
#Se crea la grafica en coordenadas polares pasando
#el angulo theta y los valores de r
plt.polar(theta, r)
#Se crea una grilla de los angulos 45,90 y 369
plt.thetagrids(range(45, 360, 90))
plt.rgrids(np.arange(0.2, 3.1, .7), angle=0);
#Se genera la grafica
plt.show()


A continuación se va a crear la gráfica de la misma ecuación utilizando pyQT.

La gráfica se muestra en la siguiente figura:

La figura muestra la ventana ahora con un título, la barra inferior de herramienta de navegación.

El código para generar la gráfica:
#!/usr/bin/env python
#Importar numpy 
import numpy as np
# Importar el objeto Figure de matplotlib
from matplotlib.figure import Figure

#Importar el Objeto FigureCanvas de Qt4Qgg,
#Se heredara desde QWidget.
from matplotlib.backends.backend_qt4agg \
  import FigureCanvasQTAgg as FigureCanvas

#Importar el widget de la barra de navegacion 
# import the NavigationToolbar Qt4Agg widget
from matplotlib.backends.backend_qt4agg \
  import NavigationToolbar2QTAgg as NavigationToolbar

#Importar QTGui de PyQt4.
from PyQt4 import QtGui

#Se crea la Clase Qt4MplCanvas heredando FigureCanvas
class Lienzo(FigureCanvas):
    
    def __init__(self, parent):
        # Se instancia el objeto figure
        self.fig = Figure()
        #Se define la grafica en coordenadas polares
        self.axes = self.fig.add_subplot(111,polar=True)
        #Se crea el rango de valores angulares
        theta = np.arange(0., 2., 0.005)*np.pi
        #Se calcula el coseno del rango de valores angulares
        r = 2*np.abs(np.cos(theta))
        #Se genera la grafica pasando theta y r.
        self.axes.plot(theta, r)
        # se inicializa FigureCanvas
        FigureCanvas.__init__(self, self.fig)
        # se define el widget padre
        self.setParent(parent)
        # se define el widget como expandible
        FigureCanvas.setSizePolicy(self,
                                   QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)
        # se notifica al sistema de la actualizacion de la politica
        FigureCanvas.updateGeometry(self)

#Se crea la clase Ventana que hereda QMainWindow
class Ventana(QtGui.QMainWindow):
    
    def __init__(self):
        
        #Inicializacion del widget QMainWindow
        QtGui.QMainWindow.__init__(self)
        # se define el titulo de la ventana
        self.setWindowTitle("Ventana PyQT con una grafica de matplotlib")
        # instantiate a widget, it will be the main one
        # Se instancia el widget.
        self.main_widget = QtGui.QWidget(self)
        
        #Se crea una layout vbox
        vbl = QtGui.QVBoxLayout(self.main_widget)
        
        #Se instancia el Lienzo con la grafica de Matplotlib
        qmc = Lienzo(self.main_widget)
        # se instancia la barra de navegacion
        ntb = NavigationToolbar(qmc, self.main_widget)
        # se empaqueta el lienzo y la barra de navegacion en el vbox
        vbl.addWidget(qmc)
        vbl.addWidget(ntb)
        # se le asigna foco a la ventana
        self.main_widget.setFocus()
        #Se define el widget central
        self.setCentralWidget(self.main_widget)

if __name__ == '__main__':
    #Importar sys
    import sys
    #Importar QtGui de PyQt4
    from PyQt4 import QtGui
    #Se crea la aplicacion grafica
    qApp = QtGui.QApplication(sys.argv)
    # se instancia la ventana
    aw = Ventana()
    # se muestra el widget
    aw.show()
    #Se inicia el lazo principal de QT
    sys.exit(qApp.exec_())

6 jun. 2011

Generando una gráfica en python con matplotlib con PyQT. Parte 11

A partir de este artículo las gráficas con matplotlib se explicarán con la librería gráfica PyQT. Para ello en otros artículos se reiniciará la serie sobre pyQT.

En este artículo se tomará las funciones creadas en el artículo anterior para calcular la trayectoria del lanzamiento de proyectil y se creará un objeto basandose en las librerías PyQT.

El código se muestra a continuación:
#!/usr/bin/env python #Para los argumentos desde la linea de comandos import sys # Importar GUI de PyQT from PyQt4 import QtGui # Importar numpy para la creacion de la imagen import numpy as np # Se importa el objeto Figure de Matplotlib from matplotlib.figure import Figure #Se importa QT4Agg como Canvas. from matplotlib.backends.backend_qt4agg \   import FigureCanvasQTAgg as FigureCanvas #Se define la funcion x(t) de la ecuacion de posicion (movimiento horizontal) def fx (t):     #Se define la posicion inicial en 0     x0 = 0     #Se define la velocidad inicial en 2 mts/seg     v0x = 2     #Se define la aceleracion en 1 mts/seg^2     ax = 1     #Se hace el calculo de la posicion con respecto al tiempo     x = x0 + v0x*t + 0.5*ax*t**2     return x #Se define la funcion y(t) de la ecuacion de posicion altura def fy(t):     #Se define la altura inicial en 100 mts     y0 = 100     #Se define la velocidad inicial en 10 mts/seg     v0y = 10     #Se define la gravedad en 9.81 mts/seg^2     g = 9.81     #Se realiza el calculo de l posicion en funcion del tiempo     y = y0 + v0y*t - 0.5*g*t**2     return y class Lienzo(FigureCanvas):     """Clase que represente a FigureCanvas"""     def __init__(self):         # Codigo para generar la grafica         self.figura = Figure()         self.ejes = self.figura.add_subplot(111)         self.tiempo = np.arange(0.0, 5.65, 0.01)         #Calculo de la posicion en el eje X y Y         self.x = fx(self.tiempo)         self.y = fy(self.tiempo)         #Se crea la grafica         self.ejes.plot(self.x, self.y)         # inicializar el lienzo donde se crea la grafica.         FigureCanvas.__init__(self, self.figura)         if __name__ == '__main__':     # Se crea el GUI de la aplicacion     qApp = QtGui.QApplication(sys.argv)     # Se crea el widget para matplotlib        mpl = Lienzo()     # Se muestra el widget.     mpl.show()     #Se inicia el lazo de ejecucion de QT.     sys.exit(qApp.exec_())

La siguiente figura muestra la gráfica de la trayectoria del lanzamiento de proyectil.

5 jun. 2011

Generando una gráfica en python con matplotlib. Parte 10

Revisando algunos scripts que tengo en mi equipo me encontre con uno que hace  el cálculo de la física de un lanzamiento vertical.

La precisión del cálculo se logra con un arreglo donde se define los datos de la variable tiempo.

Esto se logra gracias al modulo numpy que permite crear un arreglo de valores decimales con valores específicos entre cada elemento del arreglo.

Si se necesita un arreglo con valores desde 0 a 5,6 con elementos entre 0,1 se ejecuta la siguiente instrucción:

import numpy as np
arreglo = np.arange(0, 5.60,0.1)
print arreglo
[ 0.   0.1  0.2  0.3  0.4  0.5  0.6  0.7  0.8  0.9  1.   1.1  1.2  1.3  1.4
  1.5  1.6  1.7  1.8  1.9  2.   2.1  2.2  2.3  2.4  2.5  2.6  2.7  2.8  2.9
  3.   3.1  3.2  3.3  3.4  3.5  3.6  3.7  3.8  3.9  4.   4.1  4.2  4.3  4.4
  4.5  4.6  4.7  4.8  4.9  5.   5.1  5.2  5.3  5.4  5.5]

Se tiene 2 funciones una fx(t) y otra fy(t) ambas realizan los cálculos de la posición de un cuerpo para lanzamiento vertical, se calcula se tiene el tiempo que se tarda en caer el cuerpo hasta el piso desde una altura de 100 mts con una velocidad inicial en X y Y y la aceleración en el eje X y la gravedad.

Simplemente se usa matplotlib para generar el gráfico, en un próximo artículo se mostrará como usar glade+python+gtk con matplotlib para tener las dos gráficas que se muestran en la siguiente figura:
La primera gráfica muestra la trayectoria del cuerpo con respecto a su altura versus el tiempo que tarda en caer.
La segunda gráfica muestra la trayectoria con respecto a la altura y la distancia horizontal, sería una descripción de la trayectoria del lanzamiento del cuerpo.

El código donde se realiza el cálculo y las gráficas se muestra a continuación:
#!/usr/bin/env python # -*- coding: utf-8 -*- #Se importa el modulo numpy para generar un arreglo con los datos de la variable tiempo import numpy as np #Se importa matplotlib para generar la grafica. import matplotlib.pyplot as plt #Se define la funcion x(t) de la ecuacion de posicion (movimiento horizontal) def fx (t):     #Se define la posicion inicial en 0     x0 = 0     #Se define la velocidad inicial en 2 mts/seg     v0x = 2     #Se define la aceleracion en 1 mts/seg^2     ax = 1     #Se hace el calculo de la posicion con respecto al tiempo     x = x0 + v0x*t + 0.5*ax*t**2     return x #Se define la funcion y(t) de la ecuacion de posicion altura def fy(t):     #Se define la altura inicial en 100 mts     y0 = 100     #Se define la velocidad inicial en 10 mts/seg     v0y = 10     #Se define la gravedad en 9.81 mts/seg^2     g = 9.81     #Se realiza el calculo de l posicion en funcion del tiempo     y = y0 + v0y*t - 0.5*g*t**2     return y #Programa principal def main():     #Se define un range desde 0 a 5.65 con intervalos de 0.01.     tiempo = np.arange(0, 5.65,0.01)     #Se define la figura     plt.figure(1)     #Se define la grafica.     plt.subplot(211)     #Se despligega la grafica de la distancia en X en funcion del tiempo     plt.plot(tiempo, fy(tiempo),"k")     #Se Coloca un titulo a la grafica y la informacion del eje y (tiempo)     plt.title("Graficas posicion")     plt.xlabel("tiempo (seg)")     plt.ylabel("Altura en mts")     #Se muestra la grafica de posicion en X respecto a la altura.     plt.subplot(212)     #Se grafica la funcion fx vs fy     plt.plot(fx(tiempo),fy(tiempo),'k')     #Se muestra la info del eje X y Y     plt.xlabel("Distancia horizontal (mts)")     plt.ylabel("Altura  (mts)")     #Se muestra las graficas.     plt.show()     if __name__ == "__main__":     main()  
Como mencione antes, en un siguiente artículo se mostrará este mismo ejemplo pero usando glade.