Pular para o conteúdo principal

Formas de Plotly: Um guia para anotar e estilizar enredos

Saiba como elevar a narrativa de seus dados com as formas do Plotly. Este guia fornece um passo a passo abrangente para você adicionar e estilizar anotações em Python, desde retângulos e linhas básicos até geometrias interativas avançadas.
Atualizado 27 de jun. de 2025  · 12 min lido

O Plotly é uma das bibliotecas Python mais poderosas e populares para a criação de gráficos interativos. Embora a criação de gráficos básicos com o Plotly seja simples, as visualizações de dados realmente impactantes geralmente exigem elementos adicionais que orientem a atenção do visualizador e forneçam um contexto importante. É nesse ponto que as formas do Plotly se tornam valiosas.

As formas são elementos gráficos, como retângulos, linhas e círculos, que você pode desenhar sobre as figuras do Plotly para fazer anotações, destacar e adicionar contexto crucial. Eles são a chave para transformar um gráfico padrão em uma visualização rica, perspicaz e com qualidade de publicação.

formas plotadas

Imagem do autor

Neste artigo, veremos tudo o que você precisa saber sobre formas de plotagem, desde a implementação básica até técnicas avançadas de personalização. Para aqueles que estão começando a usar o Plotly, sentir-se confortável com sua interface de alto nível é um ótimo primeiro passo, e este Introdução à visualização de dados com Plotly em Python pode ajudar você a dominar os fundamentos antes de se aprofundar em personalizações como formas.

O que são formas de plotagem?

Formas de plotagem são gráficos vetoriais desenhados em uma figura para fornecer contexto adicional ou destacar áreas específicas. Essas anotações são importantes para a criação de gráficos que não sejam apenas visualmente atraentes, mas também ricos em informações.

A importância das formas na visualização de dados

Na visualização de dados, a clareza é importante. Enquanto os gráficos, como os de dispersão ou de barras, apresentam os dados, as formas ajudam a contar a história por trás dos dados. Eles têm duas funções principais:

  • Destacar tendências de dados: As formas podem chamar a atenção para períodos ou eventos importantes em seus dados. Por exemplo, você pode usar um retângulo para sombrear um período de recessão em um gráfico de série temporal do PIB ou desenhar uma linha para marcar uma mudança significativa na política. Essa dica visual ajuda o visualizador a entender imediatamente o impacto de fatores externos nos dados.
  • Fornecimento de anotações contextuais: As formas podem circundar ou apontar para pontos ou grupos de dados específicos, como outliers, grupos de interesse ou limites críticos. Imagine um gráfico de controle de qualidade em que você usa círculos para sinalizar as medições que estão fora dos limites aceitáveis. Isso torna a interpretação dos dados mais rápida e intuitiva.

Se você quiser dar uma olhada rápida nas visualizações de dados mais comuns, quando usá-las e seus casos de uso mais comuns, confira nossa Folha de consulta de visualização de dados.

Visão geral dos tipos de formas no Plotly

O Plotly oferece suporte a vários tipos de formas geométricas que podem ser adicionadas ao layout de uma figura. Cada um deles é definido por seu site type e por parâmetros de coordenadas específicos.

Aqui está uma breve olhada nas formas primárias:

  • Retângulo (type: 'rect'): Definido por dois cantos opostos (x0, y0) e (x1, y1). Os retângulos são perfeitos para sombrear regiões de interesse ou destacar uma janela específica de dados.
  • Linha (type: 'line'): Definido por um ponto inicial (x0, y0) e um ponto final (x1, y1). As linhas são excelentes para criar linhas de tendência, limites ou marcas de referência.
  • Círculo (type: 'circle'): Definido por um centro (x0, y0) e um raio. Os círculos são ideais para enfatizar pontos de dados individuais ou pequenos grupos. Observe que a criação de um círculo geralmente envolve a definição de uma proporção igual para os eixos (fig.update_layout(yaxis_scaleanchor="x")) para evitar que ele se pareça com uma forma oval.
  • Caminho (type: 'path'): Definido por uma string de caminho SVG. Os caminhos permitem que você desenhe formas complexas e livres, inclusive polígonos. Você fornece uma sequência de comandos (como M para mover, L para alinhar a, Z para fechar caminho) para desenhar qualquer forma que precisar. Essa é a opção mais versátil para criar anotações geométricas personalizadas.

Compreender esses tipos básicos é a primeira etapa para que você domine as anotações visuais em suas figuras do Plotly.

Adicionando formas aos gráficos do Plotly

A implementação de formas de plotagem em suas visualizações envolve a compreensão de duas abordagens principais: o método add_shape() para formas individuais e a abordagem update_layout() para várias formas. Ambos os métodos oferecem vantagens exclusivas, dependendo do seu caso de uso específico e das preferências de fluxo de trabalho. Vamos ver como você pode adicionar formas usando o método add_shape().

Como adicionar formas usando add_shape()?

O principal método para adicionar uma única forma a uma figura do Plotly é fig.add_shape(). O método add_shape() é uma função do objeto plotly.graph_objects.Figure. Primeiro, você cria a figura de base (por exemplo, um gráfico de dispersão ou de linhas) e, em seguida, chama esse método para colocar a forma na parte superior. 

Isso é particularmente útil quando você precisa adicionar formas de forma programática com base em determinadas condições ou valores de dados. Vejamos um exemplo básico em que destacamos uma região específica em um gráfico de série temporal.

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()

Saída:

Adicione formas ao gráfico usando add_shape()

A funcionalidade do plotly add_shape() torna-se particularmente poderosa quando você entende o sistema de coordenadas. As formas podem fazer referência a diferentes sistemas de coordenadas usando os parâmetros xref e yref. Vamos modificar o gráfico acima usando esses parâmetros, conforme mostrado abaixo:

# 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)")

Saída:

Personalização de retângulos e linhas

Retângulos e linhas são as formas mais comumente usadas para anotações. O Plotly oferece amplas opções de personalização para você controlar sua aparência. Para que você tenha uma referência rápida sobre a sintaxe comum do Plotly, a Folha de dicas do Plotly Express é um recurso inestimável. Vamos ver como você pode personalizar essas formas.

Personalização do formato do retângulo

Os retângulos são definidos por dois pontos (x0,y0 e x1, y1). Você pode estilizar o preenchimento e a borda separadamente.

# 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
)

Saída:

Personalização da forma do retângulo do Plotly

Personalização da forma da linha

As linhas podem ser adicionadas usando os métodos especializados 'add_hline' e 'add_vline' para linhas horizontais e verticais que abrangem todo o gráfico, ou por meio do método geral 'add_shape' para um controle mais preciso. Vejamos um exemplo:

# 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"
    )
)

Saída:

Personalização da forma da linha Plotly

Esses exemplos demonstram a facilidade com que você pode adicionar e estilizar formas fundamentais do Plotly para tornar seus gráficos mais informativos.

Configuração e personalização avançadas

Além de adicionar formas básicas, o Plotly oferece ferramentas avançadas para gerenciar várias formas e controlar sua hierarquia visual. Esses recursos avançados são essenciais para a criação de visualizações complexas, em camadas e dinâmicas. Vejamos algumas maneiras de configurar e personalizar os gráficos.

Usando plotly.update_layout para atualizações dinâmicas

Embora o método add_shape() seja perfeito para adicionar formas uma a uma, o método update_layout() é uma maneira mais eficiente de gerenciar uma coleção de formas, especialmente quando elas são geradas programaticamente. Em vez de chamar uma função para cada forma, você pode passar uma lista de dicionários de formas diretamente para o argumento shapes em update_layout()

Vamos ver um exemplo de uso desse 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()

Saída:

Usando plotly.update_layout para atualizações dinâmicas

Esse método é particularmente eficiente para aplicativos dinâmicos, como um painel do Dash, em que as formas precisam mudar com base na entrada do usuário. Você pode gerar uma nova lista de objetos de forma e atualizar o layout em uma operação única e limpa. Essa abordagem mantém seu código organizado e, em geral, é mais eficiente para adicionar um grande número de formas de uma só vez.

Controle de camadas e z-index

Quando você adiciona formas a um gráfico, é importante controlar se elas aparecem em cima ou atrás dos dados. O Plotly gerencia isso por meio da propriedade de camada. Embora não seja um z-index granular como no CSS, ele oferece controle essencial sobre o empilhamento visual.

A propriedade layer pode ser definida com um de dois valores:

  • 'above': A forma é desenhada sobre os traços de dados. Essa é a configuração padrão e é útil para anotações que devem ser claramente visíveis.
  • 'below': A forma é desenhada abaixo dos traços de dados e das linhas de grade. Isso é ideal para sombrear o fundo ou destacar regiões sem obscurecer os próprios pontos de dados.

A ordem das formas dentro da seção formas também é importante: as formas definidas posteriormente na lista serão desenhadas sobre as definidas anteriormente (na mesma camada).

Aqui está um exemplo que demonstra o efeito das camadas:

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()

Saída:

Controle de camadas e z-index

Como você pode ver, o retângulo rosa fica atrás dos marcadores, enquanto o círculo verde sobrepõe o ponto de dados. 

Se você dominar essas técnicas de layout e camadas, será fundamental para criar visualizações de dados mais avançadas e interativas com o Plotly. Para quem trabalha em R, aplicam-se conceitos semelhantes, conforme explorado em Intermediate Interactive Data Visualization with Plotly in R.

Edição interativa de formas

Um dos recursos mais poderosos do Plotly é sua interatividade. Você pode tornar as formas do Plotly editáveis, permitindo que os usuários as arrastem, redimensionem e girem diretamente no gráfico. Esse recurso é ativado pela configuração editable=True na definição da forma. Vamos ver um exemplo de como fazer isso:

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}})

Saída:

Edição interativa de formas

As formas interativas são incrivelmente úteis para a análise exploratória de dados. Por exemplo, um usuário poderia arrastar um retângulo sobre diferentes períodos de tempo para ver as estatísticas resumidas correspondentes atualizadas em tempo real em um aplicativo Dash. Ou, eles podem redimensionar um círculo para selecionar um grupo diferente de pontos para uma investigação mais aprofundada.

Embora seja eficiente, lembre-se de que o uso intenso de formas editáveis pode ter implicações de desempenho em aplicativos da Web complexos. No entanto, para criar ferramentas realmente dinâmicas e orientadas ao usuário, elas são indispensáveis. 

A exploração da interatividade é uma parte importante da visualização de dados moderna, um tópico bem abordado em cursos como Visualização interativa de dados com Plotly em R, que compartilha muitos princípios com seu equivalente em Python.

Integração do Plotly com outras bibliotecas

Embora as formas integradas do Plotly sejam versáteis, às vezes você precisa criar geometrias altamente complexas ou personalizadas. Ao integrar-se a bibliotecas especializadas, como a Shapely, você pode definir polígonos sofisticados e adicioná-los às suas visualizações como formas personalizadas do Plotly.

Usando o Shapely para formas geométricas avançadas

Shapely é uma biblioteca Python avançada para a manipulação e análise de objetos geométricos planos. É a ferramenta ideal para geometria computacional, usada com frequência em análises geoespaciais. Você pode usá-lo para criar formas complexas, como uma união de dois círculos sobrepostos ou um polígono com um furo, e depois visualizá-las no Plotly.

O processo envolve duas etapas principais:

  1. Defina a forma complexa usando o Shapely.
  2. Extraia as coordenadas do objeto Shapely e formate-as como uma string de caminho SVG, que o Plotly pode renderizar usando type: 'path'.

Uma string de caminho SVG é uma mini-linguagem para desenho. Ele usa comandos como M (moveto) para definir um ponto de partida, L (lineto) para desenhar uma linha até um novo ponto e Z para fechar o caminho desenhando uma linha de volta ao início.

Vamos ver como você pode criar um polígono com um recorte e adicioná-lo a uma figura do 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()

Saída:

Usando o Shapely para formas geométricas avançadas

Essa técnica é inestimável para aplicações geoespaciais, como a plotagem de territórios de vendas personalizados, ou em contextos científicos em que você pode precisar destacar áreas irregulares de interesse. 

Entender como são criados os diferentes tipos de gráficos de dados e como eles podem ser aprimorados com essas ferramentas é uma habilidade fundamental para qualquer profissional de dados. Você pode saber mais sobre os diferentes tipos de plotagem neste guia sobre como criá-los em Python.

Personalização de estilo e estética

A aparência padrão das formas do Plotly é funcional, mas a personalização de seu estilo é importante para que você crie uma visualização polida e de aparência profissional. O uso cuidadoso de cores, opacidade e preenchimentos pode melhorar significativamente a legibilidade e o apelo estético.

Preenchimentos de cor, opacidade e padrão

O Plotly oferece a você um controle refinado sobre a aparência das formas, permitindo que você as combine com o esquema de cores e a linguagem de design do seu gráfico.

Para um controle preciso da cor e da transparência, é altamente recomendável usar a especificação de cor RGBA (Red, Green, Blue, Alpha). O canal a (alfa) controla a opacidade, sendo que um valor de 1 é totalmente opaco e 0 é totalmente transparente .

Isso é essencial para a criação de destaques não intrusivos, em que a forma adiciona contexto sem ocultar completamente os dados que estão por baixo. Você pode fornecer valores RGBA como uma cadeia de caracteres, como 'rgba(255, 99, 71, 0.5)'. Vamos ver um exemplo:

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()

Saída:

Preenchimentos de cor, opacidade e padrão

Estratégias de simulação de preenchimento de padrões

Embora o Plotly não ofereça suporte nativo a preenchimentos de padrões, os profissionais de dados podem simular padrões de preenchimento complexos usando técnicas criativas. Por exemplo, podemos criar padrões no gráfico usando uma função, conforme mostrado abaixo:

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()

Estratégias de simulação de preenchimento de padrões

Simulação de efeito de gradiente

Para criar efeitos de gradiente, você precisa de camadas estratégicas de várias formas com opacidade variável. Podemos criar usando a mesma estratégia que usamos para criar os padrões, conforme mostrado abaixo:

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()

Saída

Simulação de efeito de gradiente

Solução de problemas e otimização

Embora a adição de formas do Plotly seja geralmente simples, você pode encontrar problemas de alinhamento ou desempenho, especialmente em gráficos complexos. Compreender essas armadilhas comuns e saber como resolvê-las poupará muito tempo e esforço a você.

Problemas comuns com o alinhamento da forma

Um dos desafios mais frequentes é fazer com que as formas apareçam exatamente onde você deseja. Uma linha destinada a abranger toda a largura do gráfico pode não ser suficiente, ou um retângulo pode não se alinhar com as linhas de grade conforme o esperado. Esses problemas quase sempre decorrem de referências incorretas de coordenadas.

O Plotly usa dois sistemas de coordenadas para posicionar formas:

  • Coordenadas dos dados (xref: 'x', yref: 'y' ): Esse é o padrão. A posição da forma está vinculada aos valores nos eixos x e y. Por exemplo, x0=50 coloca o ponto na marca de 50 no eixo x.
  • Coordenadas do papel (xref: 'paper', yref: 'paper' ): A posição é relativa à própria área de plotagem, em que 0 é o início (borda esquerda/inferior) e 1 é o fim (borda direita/superior). Esse sistema é independente dos valores de dados ou intervalos de eixos.

O problema: Você deseja desenhar uma linha horizontal em todo o gráfico em y=10. Se você o definir com x0 e x1 usando coordenadas de dados, ele abrangerá apenas o intervalo do eixo atual. Se o usuário aplicar zoom ou panorâmica, a linha não se estenderá até as novas bordas.

A solução: Para fazer uma forma abranger toda a largura ou altura da área de plotagem, use as coordenadas 'paper' para o eixo que você deseja abranger.

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()

Saída:

Sempre verifique novamente as propriedades xref e yref para garantir que as formas se comportem como esperado durante a interação do usuário, como zoom e panorâmica.

Considerações sobre o desempenho

Se você adicionar um punhado de formas a um gráfico, o impacto no desempenho será insignificante. No entanto, adicionar centenas ou milhares de formas pode tornar a renderização e a interatividade significativamente mais lentas. Cada forma é um elemento SVG (Scalable Vector Graphics) individual adicionado ao DOM da página da Web. Um grande número de elementos DOM sobrecarregará o navegador.

Aqui estão as estratégias para otimizar o desempenho:

  • Limite o número de formas: A solução mais simples. Se você precisar visualizar milhares de áreas retangulares, considere se um tipo diferente de gráfico, como um go.Heatmap, poderia representar as mesmas informações de forma mais eficiente como um único traço em vez de milhares de objetos de forma.
  • Use o site update_layout para adições em massa: Conforme mencionado anteriormente, adicionar uma lista de formas via fig.update_layout(shapes=...) é mais eficiente do que chamar fig.add_shape() em um loop.
  • Considere os rastreamentos WebGL para dados: Embora as formas em si sejam renderizadas como SVG, você pode melhorar o desempenho geral de um gráfico complexo usando traços baseados em WebGL (por exemplo, go.Scattergl) para seus dados principais. Isso transfere a renderização de dados para a GPU, liberando a CPU para lidar com as formas SVG de forma mais suave. Isso é útil quando você tem um grande número de pontos de dados e um número moderado de formas.

Para a maioria dos casos de uso, a chave é estar atento ao número de elementos de forma exclusivos que você está criando. Antes de adicionar milhares de formas do Plotly em um loop, faça uma pausa e considere se existe uma estratégia de visualização com melhor desempenho.

Conclusão

Ao dominar as formas do Plotly, você transforma seus gráficos de simples representações de dados em histórias convincentes e ricas em contexto. Você já viu como desenhar linhas e retângulos básicos e como criar camadas de geometrias complexas e interativas. 

Ao aplicar essas técnicas, você pode orientar o foco do seu público, destacar insights essenciais e criar visualizações mais intuitivas que se comuniquem com clareza e impacto. 

Você está pronto para aplicar essas habilidades? Comece a criar visualizações mais eficientes hoje mesmo, explorando a seção Introdução à visualização de dados com Plotly em Python e coloque seus conhecimentos à prova.

Perguntas frequentes sobre o Plotly Shapes

Para que são usadas as formas do Plotly?

As formas do Plotly são usadas para adicionar anotações como linhas, retângulos e círculos para destacar regiões de dados importantes em um gráfico.

Como você adiciona várias formas no Plotly?

Você pode adicionar várias formas com eficiência passando uma lista de dicionários de formas para o atributo shapes em fig.update_layout().

Como você desenha uma linha vertical no Plotly?

Você pode desenhar uma linha vertical completa usando type='line' e definindo a propriedade yref='paper' para abranger toda a altura do gráfico.

Você pode colocar uma forma por trás dos dados no Plotly?

Sim, você pode colocar uma forma atrás de traços de dados definindo sua propriedade layer propriedade para 'below'.

Como você adiciona uma forma a apenas uma subparcela no Plotly?

Você pode adicionar uma forma a uma subparcela específica fornecendo os atributos xref e yref em sua definição.


Author
Rajesh Kumar
LinkedIn

Sou redator de conteúdo de ciência de dados. Adoro criar conteúdo sobre tópicos de IA/ML/DS. Também exploro novas ferramentas de IA e escrevo sobre elas.

Tópicos

Principais cursos da DataCamp

Curso

Interactive Data Visualization with plotly in R

4 h
14K
Learn how to use plotly in R to create interactive data visualizations to enhance your data storytelling.
Ver detalhesRight Arrow
Iniciar curso
Ver maisRight Arrow
Relacionado

Tutorial

Guia passo a passo para criar mapas em Python usando a biblioteca Plotly

Faça seus dados se destacarem com mapas impressionantes criados com Plotly em Python

Moez Ali

Tutorial

Introdução à plotagem com Matplotlib em Python

Este tutorial demonstra como usar o Matplotlib, uma poderosa biblioteca de visualização de dados em Python, para criar gráficos de linha, barra e dispersão com dados do mercado de ações.

Kevin Babitz

Tutorial

Tutorial do Python Seaborn Line Plot: Criar visualizações de dados

Descubra como usar o Seaborn, uma biblioteca popular de visualização de dados em Python, para criar e personalizar gráficos de linha em Python.
Elena Kosourova's photo

Elena Kosourova

line plot python

Tutorial

Gráficos de linhas no MatplotLib com Python

Este tutorial prático se aprofunda na criação e na personalização de gráficos de linhas com o Matplotlib, uma biblioteca avançada de visualização de dados em Python.
Arunn Thevapalan's photo

Arunn Thevapalan

Tutorial

Tipos de gráficos de dados e como criá-los em Python

Explore vários tipos de gráficos de dados, desde os mais comuns até os avançados e não convencionais, o que eles mostram, quando usá-los, quando evitá-los e como criá-los e personalizá-los em Python.
Elena Kosourova's photo

Elena Kosourova

Tutorial

Gráfico de linha de série temporal do Matplotlib

Este tutorial explora como criar e personalizar gráficos de linha de séries temporais no matplotlib.
Elena Kosourova's photo

Elena Kosourova

Ver maisVer mais