Saltar al contenido principal

Formas gráficas de Plotly: Guía para anotar y gráficar gráficos

Aprende a elevar tu narración de datos con las formas de Plotly. Esta guía proporciona un recorrido completo para añadir y estilizar anotaciones en Python, desde rectángulos y líneas básicos hasta geometrías interactivas avanzadas.
Actualizado 27 jun 2025  · 12 min de lectura

Plotly es una de las bibliotecas de Python más potentes y populares para crear gráficos interactivos. Aunque crear gráficos básicos con Plotly es sencillo, las visualizaciones de datos realmente impactantes suelen requerir elementos adicionales que guíen la atención del espectador y proporcionen un contexto importante. Aquí es donde las formas de Plotly adquieren un valor incalculable.

Las formas son elementos gráficos como rectángulos, líneas y círculos que puedes dibujar sobre tus figuras de Plotly para anotar, resaltar y añadir contexto crucial. Son la clave para elevar un gráfico estándar a una visualización rica, perspicaz y con calidad de publicación.

formas gráficas

Imagen del autor

En este artículo, veremos todo lo que necesitas saber sobre las formas gráficas, desde la implementación básica hasta las técnicas avanzadas de personalización. Para los nuevos en Plotly, sentirse cómodo con su interfaz de alto nivel es un gran primer paso, y este curso de Introducción a la Visualización de Datos con Plotly en Python puede ayudarte a dominar los fundamentos antes de adentrarte en personalizaciones más profundas, como las formas.

¿Qué son los gráficados?

Las formas gráficas son gráficos vectoriales dibujados sobre una figura para proporcionar un contexto adicional o resaltar áreas específicas. Estas anotaciones son importantes para construir gráficos que no sólo sean visualmente atractivos, sino también ricos en información.

La importancia de las formas en la visualización de datos

En la visualización de datos, la claridad es importante. Mientras que los gráficos de dispersión o de barras presentan los datos, las formas ayudan a contar la historia que hay detrás de los datos. Cumplen dos funciones principales:

  • Destacar las tendencias de los datos: Las formas pueden llamar la atención sobre periodos o acontecimientos clave dentro de tus datos. Por ejemplo, podrías utilizar un rectángulo para sombrear un periodo de recesión en un gráfico de series temporales del PIB o dibujar una línea para marcar un cambio político significativo. Esta señal visual ayuda al espectador a captar inmediatamente el impacto de los factores externos en los datos.
  • Proporcionar anotaciones contextuales: Las formas pueden rodear o señalar puntos o grupos de datos específicos, como valores atípicos, grupos de interés o umbrales críticos. Imagina un gráfico de control de calidad en el que utilizas círculos para marcar las mediciones que se salen de los límites aceptables. Esto hace que la interpretación de los datos sea más rápida e intuitiva.

Si quieres echar un vistazo rápido a las visualizaciones de datos más comunes, cuándo utilizarlas y sus casos de uso más habituales, consulta nuestra Hoja de trucos sobre visualización de datos.

Visión general de los tipos de formas en Plotly

Plotly admite varios tipos de formas geométricas que pueden añadirse al diseño de una figura. Cada uno de ellos se define por su type y unos parámetros de coordenadas específicos.

He aquí un breve vistazo a las formas primarias:

  • Rectángulo (type: 'rect'): Definido por dos ángulos opuestos (x0, y0) y (x1, y1). Los rectángulos son perfectos para sombrear regiones de interés o resaltar una ventana concreta de datos.
  • Línea (type: 'line'): Definido por un punto inicial (x0, y0) y un punto final (x1, y1). Las líneas son excelentes para crear líneas de tendencia, umbrales o marcas de referencia.
  • Círculo (type: 'circle'): Definido por un centro (x0, y0) y un radio. Los círculos son ideales para resaltar puntos de datos individuales o pequeños grupos. Ten en cuenta que crear un círculo suele implicar establecer una relación de aspecto igual para los ejes (fig.update_layout(yaxis_scaleanchor="x")) para evitar que parezca un óvalo.
  • Ruta (type: 'path'): Definido por una cadena de ruta SVG. Las rutas te permiten dibujar formas complejas y libres, incluidos los polígonos. Proporcionas una secuencia de comandos (como M para mover, L para línea a, Z para cerrar trayectoria) para dibujar cualquier forma que necesites. Es la opción más versátil para crear anotaciones geométricas personalizadas.

Comprender estos tipos básicos es el primer paso para dominar las anotaciones visuales en tus figuras de Plotly.

Añadir formas a los gráficos de Plotly

Implementar formas gráficas en tus visualizaciones implica comprender dos enfoques principales: el método add_shape() para formas individuales y el enfoque update_layout() para múltiples formas. Ambos métodos ofrecen ventajas únicas, según tu caso de uso específico y tus preferencias de flujo de trabajo. Veamos cómo añadir formas utilizando el método add_shape().

¿Cómo añadir formas utilizando add_shape()?

El método principal para añadir una única forma a un gráfico de Plotly es fig.add_shape(). El método add_shape() es una función del objeto plotly.graph_objects.Figure. Primero creas tu figura base (por ejemplo, un gráfico de dispersión o de líneas) y luego llamas a este método para superponer la forma. 

Esto es especialmente útil cuando necesitas añadir formas mediante programación basándote en determinadas condiciones o valores de datos. Veamos un ejemplo básico en el que resaltamos una región concreta en un gráfico de series temporales.

import plotly.graph_objects as go
import numpy as np

# Create sample data
x = np.linspace(0, 10, 100)
y = np.sin(x) + np.random.normal(0, 0.1, 100)

# Create base figure
fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=y, mode='lines', name='Signal'))

# Add a shape using add_shape method
fig.add_shape(
    type="rect",           # Shape type
    x0=2, x1=4,           # X coordinates
    y0=-2, y1=2,          # Y coordinates
    fillcolor="rgba(255, 0, 0, 0.3)",  # Fill color with transparency
    line=dict(color="red", width=2)     # Border styling
)

fig.show()

Salida:

Graficar añadiendo formas mediante add_shape()

La funcionalidad gráficando add_shape() se vuelve especialmente potente cuando entiendes el sistema de coordenadas. Las formas pueden hacer referencia a diferentes sistemas de coordenadas utilizando los parámetros xref y yref. Modifiquemos el gráfico anterior utilizando estos parámetros como se muestra a continuación:

# Shape referenced to data coordinates (default)
fig.add_shape(type="line", x0=1, x1=9, y0=0, y1=0,
              line=dict(color="green", width=3))

# Shape referenced to paper coordinates (0-1 scale)
fig.add_shape(type="rect", xref="paper", yref="paper",
              x0=0.1, x1=0.9, y0=0.1, y1=0.9,
              fillcolor="rgba(0, 0, 255, 0.1)")

Salida:

Personalizar rectángulos y líneas

Los rectángulos y las líneas son las formas más utilizadas para la anotación. Plotly proporciona amplias opciones de personalización para controlar su apariencia. Para una referencia rápida sobre la sintaxis común de Plotly, la hoja de trucos de Plotly Express es un recurso inestimable. Veamos cómo personalizar estas formas.

Personalización de la forma del rectángulo

Los rectángulos están definidos por dos puntos (x0,y0 y x1, y1). Puedes estilizar el relleno y el borde por separado.

# Advanced rectangle customization
fig.add_shape(
    type="rect",
    x0=3, x1=7,
    y0=-1.5, y1=1.5,
    # Fill properties
    fillcolor="rgba(50, 171, 96, 0.4)",
    # Line properties
    line=dict(
        color="darkgreen",
        width=3,
        dash="dashdot"  # Options: solid, dot, dash, longdash, dashdot
    ),
    # Layer control
    layer="below"  # Options: above, below
)

Salida:

Personalización de la forma del rectángulo de Plotly

Personalización de la forma de la línea

Las líneas pueden añadirse mediante los métodos especializados "add_hline" y "add_vline" para líneas horizontales y verticales que abarcan todo el gráfico, o mediante el método general "add_shape" para un control más preciso. Veamos un ejemplo:

# Horizontal threshold lines
fig.add_hline(y=1.0, line_dash="dash", line_color="red", 
              annotation_text="Upper Threshold")
fig.add_hline(y=-1.0, line_dash="dash", line_color="red", 
              annotation_text="Lower Threshold")

# Custom diagonal line
fig.add_shape(
    type="line",
    x0=0, x1=10,
    y0=-2, y1=2,
    line=dict(
        color="purple",
        width=4,
        dash="longdashdot"
    )
)

Salida:

Personalización de la forma de la línea de Plotly

Estos ejemplos demuestran lo fácil que es añadir y estilizar formas fundamentales de Plotly para que tus gráficos sean más informativos.

Configuración avanzada y personalización

Además de añadir formas básicas, Plotly ofrece potentes herramientas para gestionar múltiples formas y controlar su jerarquía visual. Estas funciones avanzadas son esenciales para crear visualizaciones complejas, por capas y dinámicas. Veamos algunas formas de configurar y personalizar los gráficos.

Usando plotly.update_layout para actualizaciones dinámicas

Mientras que el método add_shape() es perfecto para añadir formas una a una, el método update_layout() es una forma más eficaz de gestionar una colección de formas, especialmente cuando se generan mediante programación. En lugar de llamar a una función para cada forma, puedes pasar una lista de diccionarios de formas directamente al argumento shapes dentro de update_layout()

Veamos un ejemplo de utilización de este método:

import plotly.graph_objects as go
import numpy as np

# Sample scatter plot data
x_data = np.linspace(0, 10, 50)
y_data = np.sin(x_data) + np.random.normal(0, 0.1, 50)

fig = go.Figure(data=go.Scatter(x=x_data, y=y_data, mode='markers', name='Data Points'))

# Define a list of shapes to add
shapes_to_add = [
    # A rectangle highlighting a peak area
    dict(
        type="rect",
        x0=1, x1=2.5, y0=0.8, y1=1.2,
        fillcolor="rgba(255, 165, 0, 0.4)",
        line_width=0
    ),
    # A vertical line marking an event
    dict(
        type="line",
        x0=7.5, x1=7.5, y0=0, y1=1,
        yref="paper", # Span the full plot height
        line=dict(color="red", width=2, dash="dot")
    )
]

# Add all shapes at once using update_layout
fig.update_layout(
    shapes=shapes_to_add
)

fig.show()

Salida:

Usando plotly.update_layout para actualizaciones dinámicas

Este método es especialmente potente para aplicaciones dinámicas, como un panel de control Dash en el que las formas deben cambiar en función de las entradas del usuario. Puedes generar una nueva lista de objetos de forma y actualizar el diseño en una sola operación limpia. Este enfoque mantiene tu código organizado y, en general, es más eficaz para añadir un gran número de formas a la vez.

Estratificación y control del índice z

Cuando añades formas a un gráfico, es importante controlar si aparecen encima o detrás de tus datos. Plotly lo gestiona a través de la propiedad capa. Aunque no es un z-index granular como en CSS, proporciona un control esencial sobre el apilamiento visual.

La propiedad layer puede tener uno de estos dos valores:

  • 'above': La forma se dibuja sobre las trazas de datos. Esta es la configuración por defecto y es útil para anotaciones que deben ser claramente visibles.
  • 'below': La forma se dibuja debajo de las trazas de datos y las líneas de cuadrícula. Esto es ideal para sombrear el fondo o resaltar regiones sin oscurecer los propios puntos de datos.

El orden de las formas dentro de formas también importa: las formas definidas más adelante en la lista se dibujarán encima de las definidas anteriormente (dentro de la misma capa).

Aquí tienes un ejemplo que demuestra el efecto de la superposición:

import plotly.graph_objects as go

fig = go.Figure(data=go.Scatter(x=[1, 2, 3, 4, 5], y=[5, 3, 4, 2, 6], mode='markers', marker_size=20, name='Data'))

# Add a shape BELOW the data points
fig.add_shape(
    type="rect",
    x0=2.5, y0=2.5, x1=4.5, y1=4.5,
    fillcolor="LightPink",
    opacity=0.8,
    layer="below", # Key parameter
    line_width=0
)

# Add a shape ABOVE the data points
fig.add_shape(
    type="circle",
    x0=0.5, y0=4.5, x1=1.5, y1=5.5,
    fillcolor="LightSeaGreen",
    opacity=0.6,
    layer="above", # Key parameter
    line_width=0
)

fig.update_layout(
    xaxis=dict(showgrid=False), # Turn off gridlines to see effect clearly
    yaxis=dict(showgrid=False)
)

fig.show()

Salida:

Estratificación y control del índice z

Como puedes ver, el rectángulo rosa se sitúa detrás de los marcadores, mientras que el círculo verde se superpone al punto de datos. 

Dominar estas técnicas de diseño y estratificación es una parte clave de la creación de visualizaciones de datos más avanzadas e interactivas con Plotly. Para los que trabajan en R, se aplican conceptos similares, como se explora en Visualización Intermedia Interactiva de Datos con Plotly en R.

Edición interactiva de formas

Una de las características más potentes de Plotly es su interactividad. Puedes hacer que las formas de Plotly sean editables, permitiendo a los usuarios arrastrarlas, redimensionarlas y girarlas directamente sobre el gráfico. Esta función se activa configurando editable=True en la definición de la forma. Veamos un ejemplo de cómo hacerlo:

import plotly.graph_objects as go
import numpy as np

# Create a scatter plot
fig = go.Figure(go.Scatter(
    x=np.random.rand(100),
    y=np.random.rand(100),
    mode='markers'
))

# Add a draggable rectangle
fig.add_shape(
    type="rect",
    x0=0.2, y0=0.2, x1=0.5, y1=0.5,
    line=dict(color="RoyalBlue", width=2),
    fillcolor="LightSkyBlue",
    opacity=0.5,
    editable=True # This makes the shape interactive
)

fig.update_layout(
    xaxis=dict(range=[0, 1]),
    yaxis=dict(range=[0, 1]),
    # The 'newshape' button in the modebar allows drawing new shapes
    # The config dictionary enables editing of existing shapes
    dragmode='select'
)

# To enable editing, the modebar must be visible (default)
# and the plot's config can ensure editing tools are available.
fig.show(config={'edits': {'shapePosition': True}})

Salida:

Edición interactiva de formas

Las formas interactivas son increíblemente útiles para el análisis exploratorio de datos. Por ejemplo, un usuario podría arrastrar un rectángulo sobre diferentes periodos de tiempo para ver cómo se actualizan las estadísticas resumidas correspondientes en tiempo real en una aplicación Dash. O bien, podrían cambiar el tamaño de un círculo para seleccionar un grupo diferente de puntos para seguir investigando.

Aunque es potente, ten en cuenta que el uso intensivo de formas editables puede tener implicaciones de rendimiento en aplicaciones web complejas. Sin embargo, para crear herramientas verdaderamente dinámicas y orientadas al usuario, son indispensables. 

Explorar la interactividad es una parte importante de la visualización de datos moderna, un tema bien tratado en cursos como Visualización interactiva de datos con Plotly en R, que comparte muchos principios con su homólogo en Python.

Integración de Plotly con otras bibliotecas

Aunque las formas incorporadas de Plotly son versátiles, a veces necesitas crear geometrías muy complejas o personalizadas. Mediante la integración con bibliotecas especializadas como Shapely, puedes definir polígonos sofisticados y añadirlos a tus visualizaciones como formas personalizadas de Plotly.

Utilizar Shapely para formas geométricas avanzadas

Shapely es una potente biblioteca de Python para la manipulación y el análisis de objetos geométricos planos. Es la herramienta de referencia para la geometría computacional, utilizada a menudo en el análisis geoespacial. Puedes utilizarlo para crear formas intrincadas, como la unión de dos círculos superpuestos o un polígono con un agujero, y luego visualizarlas en Plotly.

El proceso consta de dos pasos principales:

  1. Define la forma compleja utilizando Shapely.
  2. Extrae las coordenadas del objeto Shapely y formatéalas como una cadena de ruta SVG, que Plotly puede representar utilizando type: 'path'.

Una cadena de ruta SVG es un minilenguaje de dibujo. Utiliza comandos como M (moveto) para establecer un punto de inicio, L (lineto) para trazar una línea hasta un nuevo punto, y Z para cerrar la trayectoria trazando una línea de vuelta al inicio.

Veamos cómo crear un polígono con un recorte y añadirlo a una figura Plotly.

import plotly.graph_objects as go
from shapely.geometry import Polygon

# 1. Create a complex shape using Shapely
# An outer rectangle
outer_coords = [(1, 1), (1, 5), (8, 5), (8, 1)]
# An inner rectangle (this will be the "hole")
inner_coords = [(3, 2), (3, 4), (6, 4), (6, 2)]

# Define the polygon with a hole
polygon_with_hole = Polygon(outer_coords, [inner_coords])

# 2. Extract coordinates and build the SVG path string
# The exterior path
exterior_x, exterior_y = polygon_with_hole.exterior.xy
path = f"M {exterior_x[0]} {exterior_y[0]}"
for x, y in zip(exterior_x[1:], exterior_y[1:]):
    path += f" L {x} {y}"
path += " Z" # Close the exterior path

# The interior path (the hole)
interior_x, interior_y = polygon_with_hole.interiors[0].xy
path += f" M {interior_x[0]} {interior_y[0]}"
for x, y in zip(interior_x[1:], interior_y[1:]):
    path += f" L {x} {y}"
path += " Z" # Close the interior path

# Create a figure
fig = go.Figure()

# Add the complex shape to the figure
fig.add_shape(
    type="path",
    path=path,
    fillcolor="LightSeaGreen",
    opacity=0.7,
    line_color="DarkSlateGray"
)

# You can add data to see how the shape interacts with it
fig.add_trace(go.Scatter(
    x=[2, 7, 4.5], 
    y=[3, 3, 1.5], 
    mode='markers', 
    marker=dict(size=15, color='DarkRed')
))

# Use scaleanchor to ensure the shape's aspect ratio is preserved
fig.update_yaxes(scaleanchor="x", scaleratio=1)
fig.show()

Salida:

Utilizar Shapely para formas geométricas avanzadas

Esta técnica es inestimable para aplicaciones geoespaciales, como gráficar territorios de venta personalizados, o en contextos científicos en los que podrías necesitar resaltar zonas irregulares de interés. 

Comprender cómo se crean los distintos tipos de gráficos de datos y cómo pueden mejorarse con dichas herramientas es una habilidad fundamental para cualquier profesional de los datos. Puedes aprender más sobre los distintos tipos de gráficos en esta guía sobre cómo crearlos en Python.

Personalización estética y de estilo

El aspecto por defecto de las formas de Plotly es funcional, pero personalizar su estilo es importante para crear una visualización pulida y de aspecto profesional. Un uso meditado del color, la opacidad y los rellenos puede mejorar significativamente la legibilidad y el atractivo estético.

Rellenos de color, opacidad y patrón

Plotly te ofrece un control detallado de la apariencia de las formas, permitiéndote adaptarlas al esquema de colores y al lenguaje de diseño de tu gráfico.

Para un control preciso del color y la transparencia, es muy recomendable utilizar la especificación de color RGBA (Rojo, Verde, Azul, Alfa). El canal a (alfa) controla la opacidad, siendo un valor de 1 totalmente opaco y 0 totalmente transparente .

Esto es esencial para crear resaltes no intrusivos, en los que la forma añade contexto sin ocultar completamente los datos que hay debajo. Puedes proporcionar los valores RGBA como una cadena como 'rgba(255, 99, 71, 0.5)'. Veamos un ejemplo:

import plotly.graph_objects as go
import numpy as np

# Create sample data for styling demonstration
x = np.linspace(0, 10, 100)
y1 = np.sin(x) + np.random.normal(0, 0.1, 100)
y2 = np.cos(x) + np.random.normal(0, 0.1, 100)

fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=y1, name='Signal 1', line=dict(color='blue')))
fig.add_trace(go.Scatter(x=x, y=y2, name='Signal 2', line=dict(color='red')))

# RGBA Color Technique 1: Graduated opacity for depth
opacity_levels = [0.15, 0.25, 0.35]
colors = ['255,0,0', '0,255,0', '0,0,255']

for i, (opacity, color) in enumerate(zip(opacity_levels, colors)):
    fig.add_shape(
        type="rect",
        x0=i*2.5, x1=(i+1)*2.5,
        y0=-3, y1=3,
        fillcolor=f"rgba({color},{opacity})",
        line=dict(color=f"rgb({color})", width=2),
        layer="below"
    )

# RGBA Technique 2: Color blending for overlapping regions
fig.add_shape(
    type="circle",
    x0=7.5, x1=9.5,
    y0=-1, y1=1,
    fillcolor="rgba(255, 255, 0, 0.4)",  # Semi-transparent yellow
    line=dict(color="orange", width=3),
    layer="below"
)

fig.update_layout(
    title="Advanced RGBA Color Techniques in Plotly Shapes",
    showlegend=True
)
fig.show()

Salida:

Rellenos de color, opacidad y patrón

Estrategias de simulación de relleno de patrones

Aunque Plotly no admite patrones de relleno de forma nativa, los profesionales de los datos pueden simular patrones de relleno complejos utilizando técnicas creativas. Por ejemplo, podemos crear patrones en el gráfico utilizando una función como la que se muestra a continuación:

def create_pattern_fill_simulation(fig, x0, x1, y0, y1, pattern_type='diagonal'):
    """Simulate pattern fills using multiple overlapping shapes"""
    
    if pattern_type == 'diagonal':
        # Create diagonal line pattern
        line_spacing = 0.2
        line_width = 1
        
        # Calculate diagonal lines
        range_x = x1 - x0
        range_y = y1 - y0
        num_lines = int((range_x + range_y) / line_spacing)
        
        for i in range(num_lines):
            offset = i * line_spacing
            
            # Calculate line endpoints for diagonal pattern
            start_x = max(x0, x0 + offset - range_y)
            start_y = max(y0, y1 - offset)
            end_x = min(x1, x0 + offset)
            end_y = min(y1, y1 - offset + range_x)
            
            fig.add_shape(
                type="line",
                x0=start_x, x1=end_x,
                y0=start_y, y1=end_y,
                line=dict(color="rgba(0, 0, 0, 0.3)", width=line_width),
                layer="above"
            )
    
    elif pattern_type == 'crosshatch':
        # Create crosshatch pattern
        spacing = 0.3
        
        # Vertical lines
        x_lines = np.arange(x0, x1, spacing)
        for x_line in x_lines:
            fig.add_shape(
                type="line",
                x0=x_line, x1=x_line,
                y0=y0, y1=y1,
                line=dict(color="rgba(100, 100, 100, 0.4)", width=1),
                layer="above"
            )
        
        # Horizontal lines
        y_lines = np.arange(y0, y1, spacing)
        for y_line in y_lines:
            fig.add_shape(
                type="line",
                x0=x0, x1=x1,
                y0=y_line, y1=y_line,
                line=dict(color="rgba(100, 100, 100, 0.4)", width=1),
                layer="above"
            )
    
    return fig

# Demonstration of pattern fill simulation
pattern_fig = go.Figure()
pattern_fig.add_trace(go.Scatter(x=[1, 2, 3, 4, 5], y=[2, 4, 3, 5, 1], 
                                mode='lines+markers', name='Data'))

# Add base rectangle
pattern_fig.add_shape(
    type="rect",
    x0=1.5, x1=3.5,
    y0=1, y1=5,
    fillcolor="rgba(200, 200, 255, 0.3)",
    line=dict(color="blue", width=2),
    layer="below"
)

# Apply pattern fill simulation
pattern_fig = create_pattern_fill_simulation(pattern_fig, 1.5, 3.5, 1, 5, 'diagonal')
pattern_fig.show()

Estrategias de simulación de relleno de patrones

Simulación del efecto gradiente

Crear efectos de degradado requiere la superposición estratégica de varias formas con opacidad variable. Podemos crear utilizando la misma estrategia que utilizamos para crear los patrones, como se muestra a continuación:

def create_gradient_effect(fig, x0, x1, y0, y1, start_color, end_color, num_bands=20):
    """Simulate gradient fill using multiple rectangular bands"""
    
    # Parse RGB values from color strings
    def parse_rgb(color_str):
        if color_str.startswith('rgb('):
            values = color_str[4:-1].split(',')
            return [int(v.strip()) for v in values]
        return [0, 0, 0]  # Default to black if parsing fails
    
    start_rgb = parse_rgb(start_color) if isinstance(start_color, str) else start_color
    end_rgb = parse_rgb(end_color) if isinstance(end_color, str) else end_color
    
    band_height = (y1 - y0) / num_bands
    
    for i in range(num_bands):
        # Calculate interpolated color
        ratio = i / (num_bands - 1)
        r = int(start_rgb[0] + (end_rgb[0] - start_rgb[0]) * ratio)
        g = int(start_rgb[1] + (end_rgb[1] - start_rgb[1]) * ratio)
        b = int(start_rgb[2] + (end_rgb[2] - start_rgb[2]) * ratio)
        
        # Calculate band position
        band_y0 = y0 + i * band_height
        band_y1 = band_y0 + band_height
        
        fig.add_shape(
            type="rect",
            x0=x0, x1=x1,
            y0=band_y0, y1=band_y1,
            fillcolor=f"rgba({r}, {g}, {b}, 0.7)",
            line=dict(width=0),  # No border for seamless gradient
            layer="below"
        )
    
    return fig

# Apply gradient effect
gradient_fig = go.Figure()
gradient_fig.add_trace(go.Scatter(x=list(range(10)), 
                                 y=np.random.randn(10).cumsum(),
                                 mode='lines', name='Time Series'))

gradient_fig = create_gradient_effect(
    gradient_fig, 2, 8, -3, 3, 
    [255, 0, 0], [0, 0, 255],  # Red to blue gradient
    num_bands=30
)
gradient_fig.show()

Salida

Simulación del efecto gradiente

Solución de problemas y optimización

Aunque añadir formas Plotly suele ser sencillo, puedes encontrar problemas de alineación o rendimiento, especialmente en gráficos complejos. Comprender estos escollos comunes y cómo abordarlos te ahorrará mucho tiempo y esfuerzo.

Problemas comunes con la alineación de formas

Uno de los retos más frecuentes es conseguir que las formas aparezcan exactamente donde quieres. Una línea destinada a abarcar toda la anchura del gráfico puede quedarse corta, o un rectángulo puede no alinearse con las líneas de la cuadrícula como se esperaba. Estos problemas casi siempre se deben a una referencia incorrecta de las coordenadas.

Plotly utiliza dos sistemas de coordenadas para gráficar formas:

  • Coordenadas de los datos (xref: 'x', yref: 'y' ): Este es el valor por defecto. La posición de la forma está vinculada a los valores de los ejes x e y. Por ejemplo, x0=50 sitúa el punto en la marca 50 del eje x.
  • Coordenadas del papel (xref: 'paper', yref: 'paper' ): La posición es relativa a la propia zona de graficado, donde 0 es el principio (borde izquierdo/inferior) y 1 es el final (borde derecho/superior). Este sistema es independiente de los valores de los datos o de los rangos de los ejes.

El problema: Quieres trazar una línea horizontal a través de todo el gráfico en y=10. Si lo defines con x0 y x1 utilizando coordenadas de datos, sólo abarcará el rango del eje actual. Si el usuario hace zoom o se desplaza, la línea no se extenderá hasta los nuevos bordes.

La solución: Para que una forma abarque toda la anchura o altura del área de gráficado, utiliza las coordenadas 'paper' para el eje que quieras abarcar.

import plotly.graph_objects as go

fig = go.Figure(data=go.Scatter(x=[0, 10], y=[0, 20]))

# Incorrect: Vertical line that might not span the full height if the user zooms out.
# This line is drawn from y=0 to y=20 in DATA units.
fig.add_shape(
    type="line",
    x0=5, y0=0, x1=5, y1=20,
    line=dict(color="Red", width=2, dash="dash"),
    name="Incorrect Line" # Name for legend
)

# Correct: Vertical line that ALWAYS spans the full plot height.
# It is drawn from the bottom edge (0) to the top edge (1) of the PLOT area.
fig.add_shape(
    type="line",
    x0=8, y0=0, x1=8, y1=1,
    yref="paper", # The key to spanning the full height
    line=dict(color="Green", width=3),
    name="Correct Line"
)

fig.update_layout(title_text="Correctly Spanning the Plot Area")
fig.show()

Salida:

Comprueba siempre dos veces tus propiedades xref y yref para asegurarte de que tus formas se comportan como esperas durante la interacción con el usuario, como el zoom y la panorámica.

Consideraciones sobre el rendimiento

Si añades un puñado de formas a un gráfico, el impacto en el rendimiento es insignificante. Sin embargo, añadir cientos o miles de formas puede ralentizar considerablemente la renderización y la interactividad. Cada forma es un elemento SVG (Scalable Vector Graphics) individual añadido al DOM de la página web. Un gran número de elementos DOM sobrecargará el navegador.

Aquí tienes estrategias para optimizar el rendimiento:

  • Limita el número de formas: La solución más sencilla. Si necesitas visualizar miles de áreas rectangulares, considera si un tipo de gráfico diferente, como go.Heatmap, podría representar la misma información de forma más eficiente como un único trazado en lugar de miles de objetos de forma.
  • Utiliza update_layout para las adiciones a granel: Como ya hemos dicho, añadir una lista de formas a través de fig.update_layout(shapes=...) es más eficaz que llamar a fig.add_shape() en un bucle.
  • Considera las trazas WebGL para los datos: Aunque las formas en sí se renderizan como SVG, puedes mejorar el rendimiento general de un gráfico complejo utilizando trazados basados en WebGL (por ejemplo, go.Scattergl) para tus datos principales. Esto descarga el renderizado de datos a la GPU, liberando a la CPU para manejar las formas SVG con mayor fluidez. Esto es útil cuando tienes un número masivo de puntos de datos y un número moderado de formas.

Para la mayoría de los casos de uso, la clave es ser consciente del número de elementos de forma únicos que estás creando. Antes de añadir miles de formas Plotly en un bucle, haz una pausa y considera si existe una estrategia de visualización de mayor rendimiento.

Conclusión

Dominar las formas de Plotly transforma tus gráficos de simples representaciones de datos en historias convincentes y ricas en contexto. Hemos pasado de dibujar líneas y rectángulos básicos a estratificar geometrías complejas e interactivas. 

Aplicando estas técnicas, puedes guiar el enfoque de tu audiencia, resaltar los puntos críticos y construir visualizaciones más intuitivas que comuniquen con claridad e impacto. 

¿Listo para aplicar estas habilidades? Empieza hoy mismo a crear visualizaciones más potentes explorando la Introducción a la Visualización de Datos con Plotly en Python y pon a prueba tus conocimientos.

Preguntas frecuentes sobre las formas de Plotly

¿Para qué sirven los gráficos de Plotly?

Las formas de Plotly se utilizan para añadir anotaciones como líneas, rectángulos y círculos para resaltar regiones de datos clave en un gráfico.

¿Cómo se añaden múltiples formas en Plotly?

Puedes añadir múltiples formas de forma eficiente pasando una lista de diccionarios de formas al atributo shapes del atributo fig.update_layout().

¿Cómo se dibuja una línea vertical en Plotly?

Puedes dibujar una línea vertical completa utilizando type='line' y estableciendo la propiedad yref='paper' para que abarque toda la altura del gráfico.

¿Puedes poner una forma detrás de los datos en Plotly?

Sí, puedes colocar una forma detrás de las trazas de datos estableciendo su propiedad layer propiedad a 'below'.

¿Cómo se añade una forma a un solo gráfico secundario en Plotly?

Puedes añadir una forma a una subparcela concreta proporcionando los botones xref y yref en su definición.


Author
Rajesh Kumar
LinkedIn

Soy redactora de contenidos de ciencia de datos. Me encanta crear contenidos sobre temas de IA/ML/DS. También exploro nuevas herramientas de IA y escribo sobre ellas.

Temas

Los mejores cursos de DataCamp

Curso

Interactive Data Visualization with plotly in R

4 h
13.9K
Learn how to use plotly in R to create interactive data visualizations to enhance your data storytelling.
Ver detallesRight Arrow
Comienza el curso
Ver másRight Arrow
Relacionado

Tutorial

Introducción al trazado con Matplotlib en Python

Este tutorial muestra cómo utilizar Matplotlib, una potente biblioteca de visualización de datos en Python, para crear gráficos de líneas, barras y dispersión con datos bursátiles.

Kevin Babitz

25 min

line plot python

Tutorial

Gráficos lineales en MatplotLib con Python

Este tutorial práctico profundiza en la creación y personalización de gráficos lineales con Matplotlib, una potente biblioteca de visualización de datos en Python.

Arunn Thevapalan

11 min

Tutorial

Tutorial de Python Seaborn Line Plot: Crear visualizaciones de datos

Descubra cómo utilizar Seaborn, una popular biblioteca de visualización de datos de Python, para crear y personalizar gráficos de líneas en Python.
Elena Kosourova's photo

Elena Kosourova

12 min

Tutorial

Gráfico lineal de series temporales Matplotlib

Este tutorial explora cómo crear y personalizar gráficos de líneas de series temporales en matplotlib.
Elena Kosourova's photo

Elena Kosourova

8 min

Tutorial

Guía paso a paso para hacer mapas en Python usando la librería Plotly

Haz que tus datos destaquen con impresionantes mapas creados con Plotly en Python
Moez Ali's photo

Moez Ali

7 min

Tutorial

Tipos de gráficos de datos y cómo crearlos en Python

Explore varios tipos de gráficos de datos, desde los más comunes hasta los más avanzados y poco convencionales, qué muestran, cuándo utilizarlos, cuándo evitarlos y cómo crearlos y personalizarlos en Python.
Elena Kosourova's photo

Elena Kosourova

15 min

Ver másVer más