Introducción
En este laboratorio, aprenderemos a crear un gráfico de burbujas empaquetadas utilizando Matplotlib en Python. El gráfico de burbujas empaquetadas es un tipo de gráfico que muestra datos en burbujas de diferentes tamaños, donde el tamaño de la burbuja representa la magnitud de los datos. Este gráfico es útil para mostrar datos escalares, donde los datos son un solo valor numérico asociado con un elemento.
Consejos sobre la VM
Una vez finalizada la inicialización de la VM, haga clic en la esquina superior izquierda para cambiar a la pestaña Cuaderno y acceder a Jupyter Notebook para practicar.
A veces, es posible que tenga que esperar unos segundos a que Jupyter Notebook termine de cargarse. La validación de las operaciones no se puede automatizar debido a las limitaciones de Jupyter Notebook.
Si tiene problemas durante el aprendizaje, no dude en preguntar a Labby. Deje sus comentarios después de la sesión y lo resolveremos rápidamente para usted.
Importar las bibliotecas necesarias
Para crear un gráfico de burbujas empaquetadas, necesitamos importar las bibliotecas matplotlib.pyplot y numpy. La biblioteca numpy se utiliza para realizar operaciones matemáticas en matrices, lo que es útil para calcular los tamaños de las burbujas.
import matplotlib.pyplot as plt
import numpy as np
Definir los datos
Los datos que utilizaremos para este ejemplo son las cuotas de mercado de diferentes navegadores de escritorio. Definiremos los datos como un diccionario que contiene los nombres de los navegadores, la cuota de mercado y el color para cada burbuja.
browser_market_share = {
'browsers': ['firefox', 'chrome','safari', 'edge', 'ie', 'opera'],
'market_share': [8.61, 69.55, 8.36, 4.12, 2.76, 2.43],
'color': ['#5A69AF', '#579E65', '#F9C784', '#FC944A', '#F24C00', '#00B825']
}
Definir la clase BubbleChart
La clase BubbleChart se utiliza para crear el gráfico de burbujas empaquetadas. La clase recibe una matriz de áreas de burbujas y un valor de espaciado entre burbujas. El método __init__ configura las posiciones iniciales de las burbujas y calcula la distancia máxima de paso, que es la distancia que cada burbuja puede moverse en una sola iteración.
class BubbleChart:
def __init__(self, area, bubble_spacing=0):
"""
Configuración para el colapso de las burbujas.
Parámetros
----------
area : array-like
Área de las burbujas.
bubble_spacing : float, valor predeterminado: 0
Espaciado mínimo entre las burbujas después del colapso.
Notas
-----
Si "area" está ordenado, los resultados pueden verse extraños.
"""
area = np.asarray(area)
r = np.sqrt(area / np.pi)
self.bubble_spacing = bubble_spacing
self.bubbles = np.ones((len(area), 4))
self.bubbles[:, 2] = r
self.bubbles[:, 3] = area
self.maxstep = 2 * self.bubbles[:, 2].max() + self.bubble_spacing
self.step_dist = self.maxstep / 2
## calcular el diseño de cuadrícula inicial para las burbujas
length = np.ceil(np.sqrt(len(self.bubbles)))
grid = np.arange(length) * self.maxstep
gx, gy = np.meshgrid(grid, grid)
self.bubbles[:, 0] = gx.flatten()[:len(self.bubbles)]
self.bubbles[:, 1] = gy.flatten()[:len(self.bubbles)]
self.com = self.center_of_mass()
Definir métodos de movimiento de burbujas
La clase BubbleChart también contiene métodos para mover las burbujas hacia el centro de masa y comprobar si chocan con otras burbujas. El método center_of_mass calcula el centro de masa de todas las burbujas, y el método center_distance calcula la distancia entre una burbuja y el centro de masa. El método outline_distance calcula la distancia entre el contorno de una burbuja y los contornos de otras burbujas, y el método check_collisions comprueba si una nueva posición de burbuja choca con otras burbujas.
def center_of_mass(self):
return np.average(
self.bubbles[:, :2], axis=0, weights=self.bubbles[:, 3]
)
def center_distance(self, bubble, bubbles):
return np.hypot(bubble[0] - bubbles[:, 0],
bubble[1] - bubbles[:, 1])
def outline_distance(self, bubble, bubbles):
center_distance = self.center_distance(bubble, bubbles)
return center_distance - bubble[2] - \
bubbles[:, 2] - self.bubble_spacing
def check_collisions(self, bubble, bubbles):
distance = self.outline_distance(bubble, bubbles)
return len(distance[distance < 0])
Definir el método de colisión de burbujas
La clase BubbleChart también contiene un método para comprobar las colisiones de burbujas y moverse alrededor de las burbujas en colisión. El método collides_with calcula la distancia entre una nueva posición de burbuja y las posiciones de otras burbujas. Si la distancia es menor que cero, significa que hay una colisión y el método devuelve el índice de la burbuja en colisión. El método collapse mueve las burbujas hacia el centro de masa y alrededor de las burbujas en colisión, y el método plot dibuja las burbujas en el gráfico.
def collides_with(self, bubble, bubbles):
distance = self.outline_distance(bubble, bubbles)
idx_min = np.argmin(distance)
return idx_min if type(idx_min) == np.ndarray else [idx_min]
def collapse(self, n_iterations=50):
"""
Mueve las burbujas hacia el centro de masa.
Parámetros
----------
n_iterations : int, valor predeterminado: 50
Número de movimientos a realizar.
"""
for _i in range(n_iterations):
moves = 0
for i in range(len(self.bubbles)):
rest_bub = np.delete(self.bubbles, i, 0)
## intenta moverse directamente hacia el centro de masa
## vector de dirección desde la burbuja hasta el centro de masa
dir_vec = self.com - self.bubbles[i, :2]
## acorta el vector de dirección para que tenga una longitud de 1
dir_vec = dir_vec / np.sqrt(dir_vec.dot(dir_vec))
## calcula la nueva posición de la burbuja
new_point = self.bubbles[i, :2] + dir_vec * self.step_dist
new_bubble = np.append(new_point, self.bubbles[i, 2:4])
## comprueba si la nueva burbuja choca con otras burbujas
if not self.check_collisions(new_bubble, rest_bub):
self.bubbles[i, :] = new_bubble
self.com = self.center_of_mass()
moves += 1
else:
## intenta moverse alrededor de una burbuja con la que chocas
## encuentra la burbuja en colisión
for colliding in self.collides_with(new_bubble, rest_bub):
## calcula el vector de dirección
dir_vec = rest_bub[colliding, :2] - self.bubbles[i, :2]
dir_vec = dir_vec / np.sqrt(dir_vec.dot(dir_vec))
## calcula el vector ortogonal
orth = np.array([dir_vec[1], -dir_vec[0]])
## prueba en qué dirección ir
new_point1 = (self.bubbles[i, :2] + orth *
self.step_dist)
new_point2 = (self.bubbles[i, :2] - orth *
self.step_dist)
dist1 = self.center_distance(
self.com, np.array([new_point1]))
dist2 = self.center_distance(
self.com, np.array([new_point2]))
new_point = new_point1 if dist1 < dist2 else new_point2
new_bubble = np.append(new_point, self.bubbles[i, 2:4])
if not self.check_collisions(new_bubble, rest_bub):
self.bubbles[i, :] = new_bubble
self.com = self.center_of_mass()
if moves / len(self.bubbles) < 0.1:
self.step_dist = self.step_dist / 2
def plot(self, ax, labels, colors):
"""
Dibuja el gráfico de burbujas.
Parámetros
----------
ax : matplotlib.axes.Axes
labels : list
Etiquetas de las burbujas.
colors : list
Colores de las burbujas.
"""
for i in range(len(self.bubbles)):
circ = plt.Circle(
self.bubbles[i, :2], self.bubbles[i, 2], color=colors[i])
ax.add_patch(circ)
ax.text(*self.bubbles[i, :2], labels[i],
horizontalalignment='center', verticalalignment='center')
Crear un objeto BubbleChart y graficar el gráfico
Para crear el gráfico de burbujas empaquetadas, necesitamos crear un objeto BubbleChart y llamar al método collapse para mover las burbujas hacia el centro de masa. Luego podemos crear una figura de matplotlib y agregar un objeto de ejes a ella. Finalmente, llamamos al método plot para dibujar las burbujas en el gráfico.
bubble_chart = BubbleChart(area=browser_market_share['market_share'],
bubble_spacing=0.1)
bubble_chart.collapse()
fig, ax = plt.subplots(subplot_kw=dict(aspect="equal"))
bubble_chart.plot(
ax, browser_market_share['browsers'], browser_market_share['color'])
ax.axis("off")
ax.relim()
ax.autoscale_view()
ax.set_title('Browser market share')
plt.show()
Resumen
En este laboratorio, aprendimos cómo crear un gráfico de burbujas empaquetadas utilizando Matplotlib en Python. Definimos los datos como un diccionario que contiene los nombres de los navegadores, la participación en el mercado y el color para cada burbuja. Luego creamos una clase BubbleChart para configurar las posiciones iniciales de las burbujas, calcular la distancia máxima de paso, mover las burbujas hacia el centro de masa y comprobar si chocan con otras burbujas. Finalmente, graficamos el gráfico utilizando matplotlib.