Não existe uma única "melhor" biblioteca de gráficos em Python, e quem disser o contrário está tentando te vender algo. A resposta honesta é que o campo se divide em um punhado de ferramentas, cada uma vencendo em um trabalho específico: um gráfico estático com qualidade de publicação, uma estatística em uma linha, um dashboard interativo, uma especificação declarativa que você pode versionar, ou um gráfico que precisa sobreviver a cem milhões de pontos. Esta análise percorre as bibliotecas que importam, no que cada uma é genuinamente boa, onde cada uma falha e — porque este site é sobre construir em Python para mercados — como elas lidam com candlesticks e grandes séries temporais.

Cada contagem de estrelas, número de downloads e licença abaixo foi verificado em relação às fontes primárias (GitHub, PyPI, documentação oficial) em meados de 2026. Onde um número é o melhor caso autodeclarado por um fornecedor, isso está sinalizado como tal.

Estrelas no GitHub das principais bibliotecas de gráficos em Python em meados de 2026 — o Matplotlib lidera com ~22,9k, com Bokeh, Plotly e Seaborn logo atrás.

O modelo mental: estático vs. interativo

A primeira bifurcação é se a saída é uma imagem estática (PNG/SVG/PDF, renderizada uma vez) ou uma figura interativa (HTML/JS, com pan-zoom-hover em um navegador).

A segunda bifurcação — que só morde quando seus dados ficam grandes — é onde os pontos são desenhados: no navegador (do lado do cliente, WebGL) ou pré-agregados no servidor em uma imagem. Essa distinção é toda a história da "camada de escala" mais adiante, e é justamente a que a maioria das análises ignora.

Matplotlib — a fundação sobre a qual tudo se apoia

O Matplotlib é a base do plotting em Python. Não é apenas uma biblioteca; é o motor de renderização sobre o qual Seaborn, os padrões do Plotnine, o mplfinance e uma dúzia de outros são construídos. Sua licença é permissiva — oficialmente "baseada na licença PSF" e compatível com BSD, então você pode embuti-lo em um produto proprietário e vendê-lo sem pensar duas vezes (documentação da licença).

Pontos fortes. Controle total. Se você consegue descrever uma marca em uma tela 2D, o Matplotlib consegue desenhá-la, e ele exporta PDF/SVG vetorial nítido para impressão. Está instalado em todo lugar e todo erro que você um dia encontrar já tem uma resposta no Stack Overflow.

Pontos fracos. A API é notoriamente de duas cabeças — uma interface pyplot com estado, no estilo MATLAB, e uma interface orientada a objetos Figure/Axes — e os tutoriais misturam as duas livremente, o que é exatamente a razão de "por que você odeia o matplotlib" ser um gênero próprio. Os padrões são datados, e estilizar um gráfico para parecer moderno leva linhas de código de verdade.

import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(10, 4))
ax.plot(df.index, df["close"], lw=1.2)
ax.set_title("BTC-USD daily close")
fig.savefig("btc.png", dpi=150, bbox_inches="tight")

Saída do Matplotlib — uma série de preços de exemplo do BTC com médias móveis de 20 e 50 dias mais um painel de volume, desenhada eixo a eixo.

Use quando precisar de uma figura estática, pronta para impressão, ou estiver construindo uma ferramenta de nível mais alto e quiser uma tela que você controla totalmente.

Seaborn — gráficos estatísticos sem o boilerplate

O Seaborn é uma camada fina e opinativa sobre o Matplotlib (BSD-3-Clause) que transforma dez linhas de manipulação de eixos em uma. Ele "fornece uma interface de alto nível para desenhar gráficos estatísticos atraentes" e se integra fortemente com o pandas — distribuições, regressões, mapas de calor e pequenos múltiplos facetados são todos uma única chamada.

import seaborn as sns
sns.set_theme()
sns.lineplot(data=returns, x="date", y="ret", hue="symbol")

Saída do Seaborn — um mapa de calor de correlação de retornos de ativos em uma única chamada, o tipo de gráfico estatístico que o Seaborn torna trivial.

Pontos fortes. Os melhores padrões estatísticos da categoria; lindo de imediato; a primeira escolha óbvia para análise exploratória de dados.

Pontos fracos. Ele herda a natureza estática do Matplotlib (sem interatividade) e, quando você precisa de um gráfico para o qual ele não tem uma função, acaba caindo de volta no Matplotlib puro de qualquer forma. É uma camada de conveniência, não uma fuga do motor.

Use quando estiver fazendo EDA em um DataFrame e quiser mapas de calor de correlação, distribuições ou gráficos de regressão rapidamente.

Plotly — o padrão interativo

O Plotly.py é a opção interativa mais amplamente adotada. Tem licença MIT, é construído sobre o plotly.js, e os números não chegam nem perto: cerca de 18,6 mil estrelas no GitHub e aproximadamente 1,24 bilhão de downloads no PyPI ao longo de todo o tempo — na ordem de 61 milhões de downloads nos últimos 30 dias (PyPI · estatísticas de download). Tooltips ao passar o mouse, zoom, pan e alternância de legenda vêm de graça, e a mesma figura é renderizada em um notebook, em uma aplicação Dash ou em um arquivo HTML estático.

import plotly.graph_objects as go

fig = go.Figure(go.Candlestick(
    x=df.index, open=df.open, high=df.high, low=df.low, close=df.close,
))
fig.update_layout(title="BTC-USDT", xaxis_rangeslider_visible=False)
fig.show()

Saída do Plotly — um candlestick interativo com uma média móvel de 20 dias; pan, zoom e hover funcionam ao vivo na versão em navegador.

Pontos fortes. Interatividade com zero JavaScript; tipos de gráfico financeiro de primeira classe (go.Candlestick, go.Ohlc); o caminho até um dashboard completo (Dash) é curto.

Pontos fracos. O bundle do plotly.js é pesado — um custo real para sites sensíveis ao tempo de carregamento da página (análise do tempo de bundle). E há um teto rígido de renderização: com traces WebGL (go.Scattergl) você pode representar até ~1 milhão de pontos, mas os navegadores permitem apenas 8 a 16 contextos WebGL por página, então na prática você consegue 4 a 8 figuras WebGL antes de bater no "Too many active WebGL contexts" (documentação de desempenho do Plotly). O zoom/pan interativo suave realisticamente aguenta até ~100–200 mil pontos.

Use quando quiser gráficos ou dashboards interativos, especialmente financeiros, e suas séries estiverem na casa dos milhares até poucos milhões de pontos.

Bokeh — interativo feito para dados grandes e em streaming

O Bokeh (BSD-3-Clause, ~20,4 mil estrelas / 4,3 mil forks) é o principal rival interativo do Plotly, com um centro de gravidade diferente: é "uma biblioteca de visualização interativa para navegadores web modernos" voltada para grandes conjuntos de dados e em streaming e aplicações orientadas por servidor (o servidor do Bokeh pode enviar atualizações ao vivo para um gráfico por um websocket).

Uma ressalva honesta que o marketing não vai te dar: "alto desempenho" é em parte autodescrição. Relatos do mundo real mostram hover/tooltips travando em conjuntos de dados tão pequenos quanto ~50 mil pontos, então ele não é automaticamente rápido em dados enormes — você ainda recorre à agregação (abaixo). Trate a vantagem do Bokeh como streaming e arquitetura de aplicação, não como contagem bruta de pontos.

from bokeh.plotting import figure, show

p = figure(x_axis_type="datetime", title="BTC-USD", height=350)
p.line(df["date"], df["close"])
show(p)

Use quando estiver construindo um dashboard que se atualiza ao vivo ou uma aplicação de dados orientada por Python e quiser controle do lado do servidor sobre a interatividade.

Altair — uma gramática declarativa de gráficos

O Altair é uma biblioteca declarativa: você descreve o que codificar (esta coluna no x, aquela na cor) e o motor Vega-Lite decide como desenhar. Os gráficos são especificações JSON, o que os torna combináveis e amigáveis ao diff.

Saída do Altair — a mesma série de preços como um gráfico declarativo de área mais linha, gerado a partir de uma especificação Vega-Lite concisa.

A pegadinha que todo recém-chegado encontra: por padrão, o Altair se recusa a plotar mais de 5.000 linhas, lançando um MaxRowsError. É uma proteção deliberada (o Altair embute os dados como JSON na especificação), não uma incapacidade de lidar com os dados — e é uma única linha para removê-la:

import altair as alt
alt.data_transformers.disable_max_rows()   # ou use o backend VegaFusion para ~100k+

alt.Chart(df).mark_line().encode(x="date:T", y="close:Q")

É uma fonte recorrente de frustração justamente porque o erro aparece no que parece ser um frame "pequeno" de 35 mil linhas (documentação de grandes conjuntos de dados).

Use quando você valoriza especificações de gráfico concisas, declarativas e reprodutíveis, e seus dados são modestos — ou você está disposto a configurar o VegaFusion para os frames maiores.

Plotnine e Pygal — fechando o campo

python from plotnine import ggplot, aes, geom_line (ggplot(df, aes("date", "close")) + geom_line())

Saída do Plotnine — os mesmos dados no estilo de gramática de gráficos do ggplot2, instantaneamente familiar para qualquer um que venha do R.

Quando seus dados ficam grandes: a camada de escala

É aqui que escolhas ingênuas desabam. Uma vez que você passa de um milhão de pontos, não dá para simplesmente entregá-los ao navegador. (Para ser preciso sobre um mito: os navegadores conseguem representar ~1M de pontos WebGL — é a suavidade interativa que se degrada, não um travamento abrupto.) Duas estratégias resolvem isso:

1. Rasterização do lado do servidor — Datashader. Em vez de enviar pontos ao navegador, o Datashader (BSD-3-Clause) os agrupa em uma grade 2D de tamanho fixo e renderiza essa grade como uma imagem, "preservando fielmente a distribuição dos dados". Seu número de destaque: um bilhão de pontos em cerca de um segundo em um laptop de 16 GB, escalando para fora da memória (out-of-core) e para a GPU via Dask (introdução · guia de grandes dados do HoloViews). Trate o número de um bilhão de pontos por segundo como o melhor caso do fornecedor — mas a abordagem (reagrupar a cada zoom/pan) é genuinamente a correta para dados densos.

import datashader as ds, datashader.transfer_functions as tf

cvs = ds.Canvas(plot_width=900, plot_height=400)
agg = cvs.points(df, "t", "price")     # df pode ser um frame Dask maior que a RAM
img = tf.shade(agg)

2. Subamostragem dependente da visão — plotly-resampler. Isso mantém toda a interatividade do Plotly, mas só renderiza os pontos que você consegue de fato ver. Sua agregação padrão MinMaxLTTB reduz cada trace a ~1.000 pontos plotados para a visão atual e então busca novamente conforme você dá zoom — a demonstração visualiza mais de 110 milhões de pontos de dados dessa forma (artigo).

from plotly_resampler import FigureResampler
import plotly.graph_objects as go

fig = FigureResampler(go.Figure())
fig.add_trace(go.Scattergl(name="price"), hf_x=ts, hf_y=price)  # mais de 100M de pontos
fig.show_dash()

Regra prática: dispersão/mapa de calor denso de milhões de pontos → Datashader; série temporal longa e interativa → plotly-resampler.

Gráficos de dados de mercado: candlesticks e OHLC

Para um fluxo de trabalho focado em trading, o destaque é o mplfinance — o pacote de gráficos financeiros da organização do Matplotlib. Ele recebe um DataFrame do pandas com um DatetimeIndex e colunas Open/High/Low/Close e desenha gráficos de candlestick, OHLC, linha, Renko e Point & Figure, com médias móveis e volume já embutidos:

import mplfinance as mpf
mpf.plot(df, type="candle", mav=(20, 50), volume=True, style="charles")

Além do mplfinance:

A comparação em um relance

Biblioteca Tipo Licença Interativa Melhor para Cuidado com
Matplotlib Estática PSF/compatível com BSD Não Controle total, impressão/PDF Verbosa, padrões datados
Seaborn Estática BSD-3 Não EDA estatística Cai para o Matplotlib no incomum
Plotly Interativa MIT Sim Dashboards, gráficos financeiros Bundle pesado; teto WebGL de ~1M de pontos
Bokeh Interativa BSD-3 Sim Streaming / aplicações de dados Não é automaticamente rápido em grandes dados
Altair Interativa BSD-3 Sim Especificações declarativas e reprodutíveis Limite padrão de 5.000 linhas
Plotnine Estática MIT Não Memória muscular do ggplot2 Apenas estática
Pygal SVG Código aberto (LGPL) Leve Gráficos vetoriais limpos na web Nicho; não para grandes dados
Datashader Raster no servidor BSD-3 Via HoloViews 10⁶–10⁹ pontos Uma imagem, não marcas vetoriais
mplfinance Estática Estilo BSD (org. mpl) Não Candlestick / OHLC Estática; combine com Plotly para interatividade

Números de popularidade verificados em meados de 2026: Plotly ≈18,6 mil estrelas / ≈1,24B de downloads; Bokeh ≈20,4 mil estrelas / 4,3 mil forks. As contagens de estrelas e downloads mudam constantemente — trate-as como instantâneos e lembre-se de que os downloads brutos do PyPI incluem CI e mirrors, então eles superestimam a adoção humana.

Como escolher, em um só fôlego

Escolha a que combina com o trabalho, não a que tem mais estrelas. A maioria dos projetos reais acaba usando duas ou três delas juntas — Seaborn para exploração, Plotly para o dashboard, mplfinance para o relatório de backtest — e esse é o resultado correto, não uma falha em padronizar.


Metodologia: as afirmações nesta análise foram cruzadas com fontes primárias (repositórios no GitHub dos projetos, PyPI e documentação oficial) e verificadas de forma adversarial; os números são instantâneos de meados de 2026. Os números de desempenho marcados como dados de fornecedores (o bilhão de pontos do Datashader, os 110M do plotly-resampler) são melhores casos reproduzíveis, não benchmarks independentes.