Visualizando vectores en 3D con Python, NumPy y Matplotlib

Visualizando vectores en 3D con Python, NumPy y Matplotlib

Con el fin de que puedas entender mejor los vectores, en esta ocasión, vamos a utilizar Matplotlib de Python para que los puedas ver representados en un espacio tridimensional.


Para quienes estáis realizando el curso de Máster en Python completo, os indico que para usar Matplotlib, puede que la extensión Pylance de Visual Studio Code, os dé muchos falsos errores.

Por lo tanto, mientras trabajo con esto, la he deshabilitado e instalado Pylint.

Instalación de NumPy y Matplotlib

Lo primero, es instalar NumPy y Matplotlib para poder hacer los import necesarios en el archivo de Python.

Si viste el capítulo anterior, no hace falta que vuelvas a instalar NumPy.

Instalar NumPy

pip install numpy

Instalar Matplotlib

pip install matplotlib

Importación de NumPy y Matplotlib en Python

Lo siguiente, es hacer los imports de cada cosa para poder usar estos módulos en el archivo de Python.

import numpy as np
import matplotlib.pyplot as plt

A partir de ahora, todo lo que esté con 'np.', pertenece al módulo NumPy y con 'plt' a Matplotlib.

Creación de un vector con coordenadas 3D

Ahora vamos a escribir las coordenas 3D que vamos a pasarle al vector.

Lo que vamos a sacar en Matplotlib, es un cubo en 3D. El reto está en saber utilizar vectores para indicarle las coordenadas que queremos dentro del cubo.

Coordenadas cartesianas en 3D

Las coordenadas cartesianas en 3D, especifican las coordenadas 'x', 'y' del 2D y añaden una tercera dimensión, la 'z'.

En la imagen, puedes ver unas líneas que ocupan el ancho, el alto y el largo del cubo.

El color verde, corresponde a las coordenadas 'y', la roja a las 'x' y la azul a la 'z'.

ejes 3d

Crear un vector NumPy para 3 dimensiones

Para especificar un punto en concreto en un cubo, necesitaremos un vector con 3 valores, uno para cada coordenada.

# Especificamos las coordenadas
X = 10
Y = 10
Z = 4

# Creamos un vector donde llevarlas como un conjunto
vector = np.array([X, Y, Z])

Crear una figura en Matplotlib

Lo siguiente, es crear una figura con el método figure() de Matplotlib.

# Creamos una figura
figura = plt.figure()

La figura es un lienzo en blanco sobre el que, después, añadiremos más elementos.

Para que se cree una ventana al ejecutar el programa y podamos ver el lienzo, tienes que utilizar la función show() de Matplotlib.

# Mostramos el resultado en una ventana
plt.show()
lienzo matplotlib

Añadir ejes en 3D con Matplotlib

Lo siguiente que vamos a hacer, es dibujar un cubo en el lienzo. Para ello, debo crear un eje.

Para crear un eje en Matplotlib, hay que utilizar el método add_subplot().

# Creamos el eje
eje = figura.add_subplot(111, projection='3d')

Argumentos de add_subplot

Primero, debemos hacer la llamada con el objeto figura, que es el lienzo. Esto hará, que el eje se muestre sobre él.

El primer argumento tiene en realidad 3 valores.

El primer 1, sirve para especificar el número de filas de ejes que se van a crear en el lienzo.

Con el segundo 1, especificamos el número de columnas de ejes que se crearán en el lienzo.

Finalmente, tenemos el último 1 que es para el índice del eje, es decir, en esas filas y columnas, donde queremos mostrarlo.

Si queremos crear un solo cubo (eje), dejamos 1 fila, 1 columna y la posición 1 en el índice.

cubo 3d matplotlib

En cambio, por ejemplo, si queremos mostrar cuatro ejes, necesitaremos 2 filas y 2 columnas.

# Creamos los ejes
eje1 = figura.add_subplot(221, projection='3d')
eje2 = figura.add_subplot(222, projection='3d')
eje3 = figura.add_subplot(223, projection='3d')
eje4 = figura.add_subplot(224, projection='3d')
lienzo matplotlib con varios gráficos 3d

El segundo argumento, el de 'projection=3d', es para indicar que queremos un eje en 3d.

Por ejemplo, si queremos otro tipo de visualización, pondríamos el valor 'rectilinear':

# Creamos el eje
eje1 = figura.add_subplot(111, projection='rectilinear')
gráfico coordenadas 2d

Posibles valores del parámetro projection

Te dejo una lista de los valores que admite el parámetro projection:

  • None
  • 3d
  • aitoff
  • hammer
  • lambert
  • mollweide
  • polar
  • rectilinear

El método scatter de Matplotlib

El método scatter de Matplotlib nos va a servir para mostrar un elemento como un punto en unas coordenadas pasadas con una lista de Python o un vector de NumPy. Sin embargo, como indiqué anteriormente, es más eficiente utilizar vectores que listas para estos propósitos.

En el primer valor de scatter, le pasamos la coordenada 'X' del vector (posición 0 del índice). En el segundo, la coordenada 'Y' (posición 1 del índice). Por último, la coordenada 'Z' (posición 2 del índice).

Ten en cuenta, que le puedes pasar valores literales en cada uno de estos argumentos, sin necesidad de usar un vector. No obstante, cuando emplees muchos vectores, verás que es mejor ir creándolos, que especificarlos directamente en los scatter que creemos.

Con el argumento 'c', estamos especificando que el elemento se muestre de un color. En concreto de color rojo (r).

Con el argumento 'marker', especificamos el tipo de marcador. En este caso, es un pequeño círculo (punto) que especificamos con el valor 'o'.

punto coordenadas cartesianas 3d

También puedes poner diferentes opciones en marker. Algunas de las más usadas son estas:

  • 'o': Un círculo
  • '.': Un punto pequeño
  • '*': Un asterisco
  • 'v': Un triángulo apuntando hacia abajo
  • '^': Un triángulo apuntando hacia arriba
  • '<': Un triángulo apuntando hacia la izquierda
  • '>': Un triángulo apuntando hacia la derecha
  • 's': Un cuadrado
  • '+': Un cruz
  • 'p': Un pentágono
  • 'd': Un diamante pequeño
  • 'x': Una cruz 'x'
  • '|': Una línea vertical
  • '_': Una línea horizontal
  • 'D': Un diamante

Probemos una de estas. Por ejemplo, un diamante:


# Utilizamos la función scatter para dibujar el vector en el eje 3D
eje.scatter(vector[0],vector[1],vector[2], c='r', marker='D')
forma diamante scatter matplotlib

Establecer el tamaño del gráfico de Matplotlib

Podemos personalizar el tamaño del gráfico que se nos crea por defecto. Para modificarlo, solo tienes que utilizar el método set_COORDENADAlim() y establecer una lista con dos valores.

#Definimos los limites del eje x,y,z
eje.set_xlim([0, X*2])
eje.set_ylim([0, Y*2])
eje.set_zlim([0, Z*2])

Tenemos que indicar set_xlim() para el eje 'X'. set_ylim() para el eje 'Y' y set_zlim() para el eje 'Z'.

Los valores de la lista, van desde el 0 hasta el doble que cada uno de estos ejes. Así nos aseguramos de que el punto quede en un buen espacio y quede en el centro.

Fíjate en los valores de cada coordenada y en los valores que aparecen en cada eje. Son exactamente el doble. Van del cero al doble de estos valores:

# Especificamos las coordenadas
X = 10
Y = 10
Z = 4
coordenadas 3d x y z

Si no quieres que algún eje empiece por 0, modifica el primer valor de la lista. También, en lugar de hacer una multiplicación en el tamaño máximo del eje, puedes poner un valor fijo. Te puedes basar en el tamaño máximo que consideres que tendrán los vectores que se le puedan pasar a la representación.

Cambiar los valores de los ejes de Matplotlib

A continuación, vamos a mostrar las letras de las coordenadas en el lienzo. Así, veremos los resultados mejor, ya que sabremos bien cuál es cada eje.

# Mostramos las letras de las coordenadas
eje.set_xlabel('X')
eje.set_ylabel('Y')
eje.set_zlabel('Z')
punto en gráfico 3d matplotlib

Lo que hacemos con el método set_COORDENADAlabel() es poner un string sobre los correspondientes ejes, por lo tanto, no necesariamente tienes que poner estas letras sin más.

# Mostramos las letras de las coordenadas
eje.set_xlabel('EJE X')
eje.set_ylabel('EJE Y')
eje.set_zlabel('EJE Z')
ejes 3d matplotlib

Ahora, si quieres añadir más puntos, solo tienes que poner otro vector con otras coordenadas (si no se superpondrán) y crear un scatter. Además, voy a quitar las constantes de coordenadas y crearé los array con valores numéricos directos, ya que cuando haya muchos vectores, no podremos estar teniendo miles de variables sueltas. Eso no sería nada eficiente. Lo he puesto así para que visualizaras mejor el código y lo asociaras bien a cada coordenada.

Aquí tienes un código de ejemplo con tres scatters, aunque pueden ser muchos más.

import numpy as np
import matplotlib.pyplot as plt

# Creamos un vector donde llevar las coordenadas como un conjunto
vector1 = np.array([10,10,4])
vector2 = np.array([0,0,0])
vector3 = np.array([17,15,7])

# Creamos una figura
figura = plt.figure()

# Creamos el eje
eje = figura.add_subplot(111, projection='3d')

# Utilizamos la función scatter para dibujar el vector en el eje 3D
eje.scatter(vector1[0],vector1[1],vector1[2], c='r', marker='D')
eje.scatter(vector2[0],vector2[1],vector2[2], c='g', marker='*')
eje.scatter(vector3[0],vector3[1],vector3[2], c='b', marker='^')

#Definimos los límites del eje x,y,z
eje.set_xlim([0,20])
eje.set_ylim([0,20])
eje.set_zlim([0,20])

# Mostramos las letras de las coordenadas
eje.set_xlabel('EJE X')
eje.set_ylabel('EJE Y')
eje.set_zlabel('EJE Z')

# Mostramos el gráfico
plt.show()
diversos puntos matplotlib

Espero que con este ejemplo, hayas podido visualizar de manera práctica uno de los infinitos usos que podemos tener con los vectores. Ya que sin un ejemplo visual, si nunca has oido hablar de vectores, puede ser algo muy abstracto.

En resumen, los vectores son conjuntos de datos para representar algo. En este caso, cada conjunto es de 3 vectores, para representar los 3 ejes, pero no necesariamente tienen porque ser tres valores.

No te pierdas nada del curso Máster en Python. Este es solo un capítulo de la inmensidad de su temario.


Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

numpy python Entrada anterior Curso de introducción a NumPy de Python
curso de Python Entrada siguiente El manejo de excepciones con Python