Trabajo un trabajo de tiempo
completo como ingeniero de sistemas de control automotriz y, por lo
general, se emplea una gran parte de mi tiempo durante el día utilizando
MATLAB/Simulink para diferentes tipos de tareas.
Recientemente
pasé un par de semanas sin una licencia individual de Matlab en el
trabajo. Por supuesto, tuve la oportunidad de usar estaciones de trabajo
con licencias compartidas en la oficina para continuar trabajando en el desarrollo de software basado en modelos . Para ese tipo de actividad, no puede simplemente evitar el problema de la licencia.
Sin
embargo, aproveché la oportunidad para agudizar mis habilidades de
Python mientras completaba algunas de las otras tareas que tenía que
hacer, principalmente al analizar los datos.
Pensé que podía compartir
algunas de las cosas que aprendí, y comencé a escribir un artículo que
de repente fue demasiado largo para una sola publicación. Así que esta
será una serie en curso de publicaciones.
En cada entrada, compartiré un
ejemplo simple pero práctico de cómo hacer una determinada tarea con
Matlab, pero usando Python. Probablemente se puede mejorar parte del
código, pero creo que puede ser útil ver estos ejemplos si eres un
principiante como yo.
¿Por qué Python?
Podría haber usado otras alternativas, como GNU Octave , que incluso tiene la misma sintaxis de Matlab o Scilab . Pero quería aprender más sobre Python, ya que es un lenguaje de programación de uso general .
Creo que esto es importante ya
que Python abre las posibilidades de individuos y empresas que no
pueden permitirse comprar una licencia costosa de MATLAB, o ya están
utilizando MATLAB para la informática científica, en cuyo caso se puede
reemplazar fácilmente con Python, reduciendo los costos de la licencia.
Matlab todavía se está
utilizando ampliamente, especialmente en las industrias automotrices y
aeroespaciales, pero el uso de Python ha crecido dramáticamente en
muchos sectores diferentes, ya que puede usarse para muchas otras cosas,
como dije, uso general.
Python no se puede comparar realmente con Matlab, ya que fueron diseñados para diferentes propósitos , pero me centraré en los casos de uso que pueden superponerse entre los dos.
Captura de pantalla de los resultados de las tendencias de Google para Matlab y Python
¿Cómo comenzar a usar Python?
En primer lugar: este no será
un curso de Python. Supongo que ya tiene una comprensión básica y desea
ver algunos ejemplos básicos de cómo usarlo. Puede aprender los
conceptos básicos muy rápidamente con toneladas de tutoriales y cursos
gratuitos.
Seguí la informática científica con la certificación de Python en Freecodecamp.org hace un tiempo, y fue genial obtener lo básico. También hay grandes recursos como Python y Geeks reales para geeks , y muchos cursos sobre Udemy , Coursera , EDX , Datacamp y otros.
💡
Python se puede escribir en cualquier editor de texto RAW, como Numpad ++ , y luego ejecutar desde el símbolo del sistema de Windows. Pero probablemente no quieras hacer eso. Si
viene de MATLAB y desea comenzar a usar Python, probablemente desee que
funcione algún tipo de interfaz de usuario o IDE (entorno de desarrollo
integrado). No hay una respuesta única o mejor aquí, así que te contaré
sobre los que he probado.
Lo primero es, por supuesto, descargar e instalar Python 3 en sí (Python
2 ya está en una etapa de fin de vida y ya no será apoyada por nuevas
bibliotecas). Luego, puede descargar e instalar uno de los siguientes
IDES:
- Jupyter Labs .
Probablemente la interfaz más utilizada para trabajar con Python hoy en
día. Le permite trabajar en su navegador web, y los cuadernos Jupyter
permiten dividir el código en celdas de MATLAB las secciones de código .
- IDE SPYDER .
En mi opinión, este proporciona la experiencia más cercana a MATLAB en
términos de interfaz. Incluso puede tener un panel para mirar las
variables con las que está trabajando, por ejemplo, y parcelas
interactivas. También puede instalar complementos para trabajar con
cuadernos Jupyter dentro del IDE Spyder.
- Visual Studio Code (VS
Code) Este es un IDE de programación de uso más general, pero tiene un
gran soporte para Python, incluido el soporte para los cuadernos Jupyter
también.
Personalmente, prefiero usar
el código VS, ya que me permite trabajar también en otros tipos de
proyectos de programación en el mismo entorno, por ejemplo, cuando
trabajo con Arduino. Sin embargo, los ejemplos de código que compartiré
funcionarán sin importar el IDE que esté utilizando.
¡De acuerdo! Suficiente con la introducción, saltemos al primer y más simple ejemplo de esta serie.
Ejemplo 1: Visualización simple de series de tiempo
Normalmente, trabajar con
MATLAB o no, lo primero que debe hacer después de cargar datos de algún
archivo grande sería trazar una serie temporal de los datos más
interesantes (o señales, si estamos hablando de un archivo de registro
de datos de lata, por ejemplo). De esta manera, al menos puedo saber con
qué estoy tratando. Para este ejemplo, usaré este archivo de ejemplo , que contiene algunos datos de lata de un automóvil eléctrico de fórmula de estudiante.
https://drive.google.com/file/d/1SntfHfiLiTw1Oucy80MRuj8r9WnVa807/view?ref=makerluis.com
Si descarga el archivo, notará
que hay valores faltantes en cada variable (señal de lata). La buena
noticia es que hay un vector de tiempo común para los diferentes
canales, aunque los datos podrían haberse transferido a diferentes tasas
sobre CAN.
Para mirar este archivo con Matlab, haría algo como esto:
filename = 'test_FSCar_ddMMYYYY_TrackN_setupID2.csv' |
%% Index non-empty values and extract time vector |
idx1 = ~isnan(t.spd_rpmFL); |
idx2 = ~isnan(t.spd_rpmFR); |
idx3 = ~isnan(t.trq_NmFL); |
idx4 = ~isnan(t.trq_NmFR); |
%% Create a figure with a tiled layout |
time_series = figure('Name', ['Time series from ' filename], 'Position', [10 10 900 600]); |
tiles = tiledlayout(2,1); |
title(tiles, 'MATLAB Plot') |
xlabel(tiles, 'Time [s]') |
%% Plot the first set of variables/signals |
plot(t.Time_s(idx1), t.spd_rpmFL(idx1), 'DisplayName', 'spd_rpmFL') |
plot(t.Time_s(idx2), t.spd_rpmFR(idx2), 'DisplayName', 'spd_rpmFR') |
legend('interpreter', 'none') |
%% Plot a second set of variables/signals |
plot(t.Time_s(idx3), t.trq_NmFL(idx3), 'DisplayName', 'trq_NmFL') |
plot(t.Time_s(idx4), t.trq_NmFR(idx4), 'DisplayName', 'trq_NmFR') |
legend('interpreter', 'none') |
Observe que extraí los índices
de los valores no vacíos de cada señal, y luego lo usé para representar
los datos. También hice algún formato a la trama para que sea
comprensible.
Necesitaba
representar datos que contengan información sobre la velocidad, en rpm y
torque, en nm. Y quería visualizar ambos en la misma escala de tiempo,
para comprender lo que sucedió durante la prueba que estoy viendo.
Es por eso que creé un diseño de azulejos. Podría haber usado subtramas en
su lugar, y los resultados habrían sido muy similares. O podría haber
trazado las velocidades y las rpm contra una sola abscisa, pero usando
dos ejes Y diferentes usando yyaxis right
.
La salida será algo como esto:

Gráfico de datos de series de tiempo obtenidas usando MATLAB - Imagen por el autor
Simple, ¿verdad? Veamos qué tenemos que hacer cuando usamos Python.
#%% Import libraries and read file as dataframe |
df = pd.read_csv('test_FSCar_ddMMYYYY_TrackN_setupID2.csv') |
#%% Index non-empty values and extract time vector |
idx1 = df.spd_rpmFL.notnull() |
idx2 = df.spd_rpmFR.notnull() |
idx3 = df.trq_NmFL.notnull() |
idx4 = df.trq_NmFR.notnull() |
time = np.array(df.Time_s).astype(np.double) |
import matplotlib.pyplot as plt |
fig = plt.figure(figsize = (1500/300, 2550/300), dpi=300) |
plt.rcParams.update({'font.sans-serif':'Helvetica'}) |
fig, ((ax1, ax2)) = plt.subplots(nrows=2, ncols=1) |
plt.suptitle('Python figure') |
# Plot the first set of variables/signals |
ax1.plot(time[idx1], df.spd_rpmFL[idx1], label = 'spd_rpmFL', linewidth = .5) |
ax1.plot(time[idx2], df.spd_rpmFR[idx2], label = 'spd_rpmFR', linewidth = .5) |
ax1.grid(b=True, which='major', color='k', linestyle='--', alpha=0.2) |
ax1.grid(b=True, which='minor', color='k', linestyle='--', alpha=0.1) |
ax1.set_ylabel('Speed [rpm]', fontsize = 11) |
ax1.legend(loc = 'upper right', fontsize = 6) |
ax1.set_title('Speed data', fontsize = 11) |
# Plot the second set of variables/signals |
ax2.plot(time[idx3], df.trq_NmFL[idx3], label = 'trq_NmFL', linewidth = .5) |
ax2.plot(time[idx4], df.trq_NmFR[idx4], label = 'trq_NmFR', linewidth = .5) |
ax2.grid(b=True, which='major', color='k', linestyle='--', alpha=0.2) |
ax2.grid(b=True, which='minor', color='k', linestyle='--', alpha=0.1) |
ax2.set_ylabel('Torque [Nm]', fontsize = 11) |
ax2.legend(loc = 'upper right', fontsize = 6) |
ax2.set_title('Torque data', fontsize = 11) |
plt.savefig('Python_fig.jpeg', dpi=300) |
La primera diferencia que notará es que necesitamos importar las bibliotecas de Python que usaremos al comienzo del código.
En este caso, estamos tratando
con datos de un archivo de texto, por lo que es una práctica común usar
la biblioteca llamada PANDAS. Puede ser lento para hacer cálculos
complejos o manejar grandes conjuntos de datos, pero hay algunas
soluciones.
En general, es mejor hacer los cálculos usando otra biblioteca, Numpy. Simplemente importamos aquellos que usan el import
comandar antes de usar cualquier cosa de ellos.
Luego podemos leer el archivo y cargar los datos como un marco de datos PANDAS.
En Python, tenemos que acostumbrarnos a trabajar con métodos distintos
de las funciones. Esto nos permitirá hacer diferentes cosas con las
variables con las que estamos trabajando, dependiendo del tipo de objeto
(clase) que sean.
Por ejemplo, cargamos los datos del archivo como un objeto DataFrame que llamamos df
(podríamos haberlo llamado algo si quisiéramos, pero df
es una práctica más autoexplicativa y común). Luego, para extraer los valores no vacíos, usamos el .
notación para acceder al notnull()
Método de la clase DataFrame.
Esto es diferente del enfoque basado en funciones que utilicé en el script de Matlab anterior, donde utilicé el isnan
función, y habría funcionado en una matriz doble, un escalar, una matriz o una matriz multidimensional.
Sin embargo, los métodos y
clases no son exclusivos de Python, existen en casi cualquier lenguaje
de programación e incluso en MATLAB. La diferencia es cómo se usan
dependiendo de la intención del idioma.
MATLAB es específico para los
cálculos de matriz, por lo que se basa en gran medida en las funciones,
mientras que Python tiene bibliotecas específicas para diferentes
propósitos, y utilizan tanto funciones como métodos para realizar
algunas tareas. También hay algunas funciones incorporadas en Python
A continuación, creamos la
figura y trazamos los datos. Primero debemos especificar el tamaño de la
figura, de lo contrario, las dimensiones de figura predeterminadas
serán demasiado pequeñas. En este caso, estamos utilizando subtramas
para obtener el siguiente resultado:
Gráfico de datos de series de tiempo obtenidas usando Python (Pyplot) - Imagen por autor
De acuerdo, la trama de Python
necesita un formato un poco más manual para tener el mismo aspecto que
el Matlab. Pero esto no es realmente un problema una vez que sepa lo que
necesita cambiar para obtener el formato que desea. Puede establecer
los valores predeterminados para crear figuras en la parte superior de
su script, o hacer una función que realice el formateo de nuevas
figuras.
Si tiene
problemas para que funcionen algunos detalles, puede buscar en Google su
respuesta. La cantidad de usuarios de Python es enorme y creciente , por lo que es muy probable que encuentre a alguien que ya haya hecho una pregunta similar en línea.
Por ejemplo, me costaba hacer que los títulos de los ejes se muestren correctamente, y había un hilo de stackoverflow que resolvía exactamente el mismo problema; resulta que necesita agregar plt.tight_layout()
para que la figura se acoltee correctamente. Solo parte de la curva de aprendizaje.
Es como cuando necesitaba llamar a la leyenda en Matlab como legend('interpreter', 'none')
Para evitar de Tex de nombres variables con subrayos, por ejemplo.
Además, este ejemplo se realizó usando el pyplot .
Hay otras bibliotecas para trazar, que pueden producir gráficos más
limpios en diferentes casos, dependiendo de sus propósitos.
Esta
publicación fue un poco más larga que las otras, siendo la introducción
de la serie, pero espero que lo hayas resultado útil o al menos
interesante. Durante las próximas semanas, compartiré otros códigos de
ejemplo, destacando las diferencias entre Matlab y Python, y mostrando
también las cosas con las que luché. Espero que estés motivado para
aprender Python, como soy, y esto puede ser un incentivo para probarlo
por tu cuenta.
Actualizaré
esta primera publicación para indexar los nuevos ejemplos que incluyo a
medida que avanzo, por lo que es más fácil navegar entre las diferentes
entradas.
¡Hasta el siguiente!
Luis
No hay comentarios.:
Publicar un comentario