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.

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).
- Estáticas: Matplotlib, Seaborn, Plotnine — e Pygal, que gera um SVG meio interativo.
- Interativas: Plotly, Bokeh, Altair.
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")

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

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

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.

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
- O Plotnine é um port quase fiel da gramática de gráficos
ggplot2do R (licença MIT). Se você veio do R ou pensa emaes()+geom_*em camadas, é a API mais natural desta lista. Ele renderiza através do Matplotlib, então é estático.
python
from plotnine import ggplot, aes, geom_line
(ggplot(df, aes("date", "close")) + geom_line())
- O Pygal gera gráficos em SVG — independentes de resolução, estilizáveis com CSS e minúsculos para embutir em um relatório ou página web. É uma escolha de nicho: ótimo para gráficos vetoriais limpos em uma página web, mas não feito para grandes volumes de dados ou interatividade pesada.

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:
- Candlesticks interativos: o
go.Candlestickdo Plotly, envolvido noplotly-resamplerquando seu histórico fica longo. - Gráficos ao vivo/em streaming: o modelo de servidor do Bokeh, ou wrappers dedicados como o
lightweight-charts-python(um binding sobre o lightweight-charts do TradingView) quando você quer exatamente aquele visual de terminal de trading. - Relatórios/backtests estáticos: mplfinance direto para PNG.
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
- Gráfico estático rápido em um notebook → Matplotlib.
- EDA estatística em um DataFrame → Seaborn.
- Gráficos interativos ou um dashboard → Plotly (ou Bokeh se for streaming / formato de aplicação).
- Especificações concisas e versionáveis → Altair (atenção ao limite de 5 mil linhas).
- Você pensa em ggplot2 → Plotnine.
- SVG limpo para uma página web ou relatório → Pygal.
- De milhões a bilhões de pontos → Datashader (denso) ou plotly-resampler (séries temporais longas).
- Candlesticks e dados de mercado → mplfinance para estático, Plotly para interativo.
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.