Skip to content

finlab.plot

Data visualization module. plot_candles() draws candlestick charts from any price series, so it works for US stocks; plot_tw_stock_radar() compares any FinLab dataset across a portfolio. The other plot_tw_stock_* helpers read Taiwan datasets and are for the Taiwan market only.

Use Cases

  • Draw stock candlestick charts with technical indicators
  • Compare financial metrics across multiple stocks (radar charts)
  • Display strategy performance statistics against a benchmark
  • Analyze strategy holdings distribution (sunburst charts)
  • Taiwan market only: market treemaps and P/E or P/B river charts

Quick Examples

Candlestick Chart with Technical Indicators

from finlab import data
from finlab.plot import plot_candles

data.set_market('us')
symbol = 'AAPL'

# Draw an Apple candlestick chart with the default Bollinger Bands and KD indicator
plot_candles(
    symbol,
    close=data.get('price:close')[symbol],
    open_=data.get('price:open')[symbol],
    high=data.get('price:high')[symbol],
    low=data.get('price:low')[symbol],
    volume=data.get('price:volume')[symbol],
    recent_days=200,
).show()

Financial Metrics Radar Chart

from finlab import data
from finlab.plot import plot_tw_stock_radar

data.set_market('us')

# Compare the latest profitability ranks of three US stocks
plot_tw_stock_radar(
    portfolio=['AAPL', 'MSFT', 'NVDA'],
    feats=[
        'us_ratios:gross_profit_margin',
        'us_ratios:operating_profit_margin',
        'us_ratios:net_profit_margin',
    ],
    mode='bar_polar',
).show()

Detailed Guide

See Data Visualization Tutorial for: - Complete examples for all visualization tools - Custom chart styles and color schemes - Interactive chart usage tips - Exporting charts as images


API Reference

All plotting functions return a plotly.graph_objects.Figure; call .show() to display it or use plotly methods to customize it.

plot_candles()

def plot_candles(
    symbol: str,
    close: pd.Series,
    open_: pd.Series,
    high: pd.Series,
    low: pd.Series,
    volume: pd.Series,
    recent_days: int = 250,
    resample: str = 'D',
    overlay_func: dict | list[dict] | None = None,
    technical_func: list[dict] | dict | None = None,
) -> go.Figure

Draw a candlestick chart with volume, overlay lines on the price panel, and technical-indicator subplots, from price series you supply. Use it for US stocks or any custom data.

Parameter Type Description
symbol str Symbol shown in the title; also used to pick the symbol's column when an indicator returns a DataFrame. stock_id is accepted as an alias.
close, open_, high, low, volume pd.Series Date-indexed price and volume series of one symbol.
recent_days int Number of most recent rows to plot.
resample str Candle period: 'D' daily, 'W' weekly, 'M' monthly.
overlay_func dict or list[dict] Lines drawn on the price panel, {name: indicator}. Defaults to Bollinger Bands from data.indicator('BBANDS').
technical_func dict or list[dict] Indicator subplots; each dict is one subplot. Defaults to the KD indicator from data.indicator('STOCH').

An indicator can be a DataFrame (from data.indicator()), a Series, a NumPy array, a callable that receives the OHLCV DataFrame, or a TA-Lib function name such as 'RSI(timeperiod=14)'.

Usage Examples:

from finlab import data
from finlab.data import indicator
from finlab.plot import plot_candles

data.set_market('us')
symbol = 'MSFT'
prices = {
    'close': data.get('price:close')[symbol],
    'open_': data.get('price:open')[symbol],
    'high': data.get('price:high')[symbol],
    'low': data.get('price:low')[symbol],
    'volume': data.get('price:volume')[symbol],
}

overlay_func = {
    'ema_20': indicator('EMA', timeperiod=20),
    'ema_60': indicator('EMA', timeperiod=60),
}
k, d = indicator('STOCH')
rsi = indicator('RSI')
technical_func = [{'K': k, 'D': d}, {'RSI': rsi}]

plot_candles(
    symbol,
    **prices,
    recent_days=300,
    overlay_func=overlay_func,
    technical_func=technical_func,
).show()

data.indicator() uses unadjusted prices by default, so pass the unadjusted price:close/open/high/low series to keep the overlay lines aligned with the candles.

Notes

  • Requires the plotly package: pip install plotly
  • TA-Lib function names require the ta-lib package
  • Call .show() to display the chart in Jupyter Notebook

plot_tw_stock_candles()

Taiwan market only

This helper reads Taiwan price datasets. For US stocks, use plot_candles() with US price series.

def plot_tw_stock_candles(
    symbol: str,
    recent_days: int = 400,
    adjust_price: bool = False,
    resample: str = 'D',
    overlay_func: dict | list[dict] | None = None,
    technical_func: list[dict] | dict | None = None,
) -> go.Figure

Draw a candlestick chart for a Taiwan stock. It loads the stock's prices and volume, then calls plot_candles().

Parameter Type Description
symbol str Taiwan stock code. stock_id is accepted as an alias.
recent_days int Number of most recent trading days to plot.
adjust_price bool Use adjusted prices.
resample str Candle period: 'D' daily, 'W' weekly, 'M' monthly.
overlay_func dict or list[dict] Lines on the price panel. Defaults to Bollinger Bands.
technical_func dict or list[dict] Indicator subplots. Defaults to one KD subplot.

Returns: plotly.graph_objects.Figure, the candlestick chart.


plot_tw_stock_radar()

def plot_tw_stock_radar(
    portfolio: list[str],
    feats: list[str] | None = None,
    mode: str = 'line_polar',
    line_polar_fill: str | None = None,
    period: str | None = None,
    cut_bins: int = 10,
    title: str | None = None,
    custom_data: pd.DataFrame | None = None,
) -> go.Figure | None

Compare the rank levels of several metrics across a portfolio. Each metric is ranked across all symbols at the chosen row and cut into cut_bins levels; missing values show no level.

Parameter Type Description
portfolio list[str] Symbols to compare, e.g. ['AAPL', 'MSFT'].
feats list[str] FinLab dataset keys to compare. The default is 18 Taiwan financial metrics, so pass feats for other markets. Axis names are the part of each key after :.
mode str 'line_polar', 'bar_polar' or 'scatter_polar' (see plotly express).
line_polar_fill str Fill for 'line_polar': None, 'toself' (close each trace into a shape) or 'tonext' (fill between consecutive traces).
period str Row label of the datasets to compare. Defaults to the latest row.
cut_bins int Number of rank levels.
title str Chart title.
custom_data pd.DataFrame Your own rank levels: index of symbols, one column per metric. Replaces feats.

Returns: plotly.graph_objects.Figure, or None (with an error log) when none of the symbols has data.

Usage Examples:

from finlab import data
from finlab.plot import plot_tw_stock_radar

data.set_market('us')

# Example 1: Compare profitability and leverage of four large caps
plot_tw_stock_radar(
    portfolio=['AAPL', 'MSFT', 'NVDA', 'AMZN'],
    feats=[
        'us_ratios:gross_profit_margin',
        'us_ratios:operating_profit_margin',
        'us_ratios:net_profit_margin',
        'us_ratios:debt_to_assets_ratio',
    ],
    mode='bar_polar',  # Bar polar chart
).show()

# Example 2: Show where one stock ranks on each metric
plot_tw_stock_radar(
    portfolio=['NVDA'],
    feats=[
        'us_ratios:gross_profit_margin',
        'us_ratios:operating_profit_margin',
        'us_ratios:net_profit_margin',
        'us_ratios:current_ratio',
        'us_ratios:debt_to_assets_ratio',
    ],
    mode='line_polar',  # Line polar chart
    line_polar_fill='toself',
    cut_bins=8,  # Split metric values into 8 levels
).show()

us_ratios:* keys hold recent daily snapshots, which suits this latest-value comparison.

mode Parameter Options

  • 'bar_polar': Bar polar chart (recommended for comparing 2-5 stocks)
  • 'line_polar': Line polar chart (suitable for single stock multi-metric display)
  • 'scatter_polar': Scatter polar chart (suitable for viewing raw data points)

plot_tw_stock_treemap()

Taiwan market only

The treemap groups stocks by Taiwan market and industry using Taiwan company data.

def plot_tw_stock_treemap(
    start: str | None = None,
    end: str | None = None,
    area_ind: str = 'market_value',
    item: str = 'return_ratio',
    clip: tuple[float, float] | None = None,
    color_continuous_scale: str = 'Temps',
    treemap_data: pd.DataFrame | None = None,
) -> go.Figure | None

Draw a nested treemap of Taiwan stocks grouped by market and industry. Block area and color show two metrics at once.

Parameter Type Description
start, end str Date range, e.g. '2024-01-02' and '2024-01-31'.
area_ind str Metric for block area: 'market_value' or 'turnover' (trading value).
item str Metric for block color: 'return_ratio' (return between start and end) or a FinLab dataset key, which shows its latest value in the range.
clip tuple Clip item to (lower, upper) so extreme values do not flatten the color scale (see DataFrame.clip).
color_continuous_scale str Name of a plotly color scale.
treemap_data pd.DataFrame Custom data in the format returned by create_treemap_data().

Returns: plotly.graph_objects.Figure, or None when the data or area_ind is unavailable.

Usage Example (Taiwan market):

from finlab.plot import plot_tw_stock_treemap

# Block area: trading value; color: return over the period
plot_tw_stock_treemap(
    start='2024-01-02',
    end='2024-01-31',
    area_ind='turnover',
    item='return_ratio',
).show()

create_treemap_data()

Taiwan market only

def create_treemap_data(
    start: str,
    end: str,
    item: str = 'return_ratio',
    clip: tuple[float, float] | None = None,
) -> pd.DataFrame | None

Build the data behind plot_tw_stock_treemap(): one row per Taiwan stock with symbol, close, turnover, return_ratio, category, market, market_value and country, plus a column for item when it is a dataset key. Add your own columns, then pass the result as plot_tw_stock_treemap(treemap_data=...).

Parameter Type Description
start, end str Date range.
item str 'return_ratio' or a FinLab dataset key whose latest value in the range is added.
clip tuple Clip item to (lower, upper).

Returns: pd.DataFrame, or None if item has no data in the range.


plot_tw_stock_river()

Taiwan market only

The river chart reads Taiwan P/E and P/B datasets.

Draw a P/E or P/B river chart for a Taiwan stock: the bands are the price implied by evenly spaced multiples between the stock's lowest and highest P/E (or P/B) in the period, and the line is the closing price, showing where the current valuation sits.

Parameter Type Description
symbol str Taiwan stock code (pass the stock you want; the default is a sample code). stock_id is accepted as an alias.
start, end str Date range, e.g. '2020-01-02' and '2024-01-05'. Default: all data.
mode str 'pe' (price-to-earnings) or 'pb' (price-to-book).
split_range int Number of bands. Default 8.

Returns: plotly.graph_objects.Figure, or None when the mode or symbol is invalid.


StrategySunburst

class StrategySunburst()

Taiwan market only. Sunburst chart of the holdings of your strategies uploaded to FinLab cloud, for monitoring several strategies at once. Requires finlab.login(). Holdings are grouped by Taiwan industry and labeled for the Taiwan site; holdings in other markets all fall under other_securities, so it is not useful for U.S. strategies.

get_strategy_df()

def get_strategy_df(self, select_strategy: dict[str, float] | None = None) -> pd.DataFrame | None

Return the combined holdings after applying strategy weights.

Parameter Type Description
select_strategy dict Strategy names and their capital weights, e.g. {'US Momentum': 0.6, 'Quality Value': 0.4}. Default: all strategies, equally weighted.

Returns: pd.DataFrame of holdings, or None when you have no strategies.

plot()

def plot(
    self,
    select_strategy: dict[str, float] | None = None,
    path: list[str] | None = None,
    color_continuous_scale: str = 'RdBu_r',
) -> go.Figure | None
Parameter Type Description
select_strategy dict Strategy names and weights, as in get_strategy_df().
path list[str] Rings from inside to outside. Default ['s_name', 'market', 'category', 'stock_id']; ['market', 'category', 'stock_id', 's_name'] shows which strategies hold each position.
color_continuous_scale str Name of a plotly color scale.

Returns: plotly.graph_objects.Figure, the holdings sunburst.


StrategyReturnStats

class StrategyReturnStats(
    start_date: str,
    end_date: str,
    strategy_names: list[str] | None = None,
    benchmark_return: pd.Series | None = None,
)

Compare the returns of your uploaded strategies with a benchmark over a period. Requires finlab.login().

Parameter Type Description
start_date str Start date of the return calculation.
end_date str End date of the return calculation.
strategy_names list[str] Names of your own strategies to include. Default: all uploaded strategies.
benchmark_return pd.Series Benchmark price series. The default is the Taiwan weighted return index, so pass one for US strategies.
Method Returns
get_benchmark_return() The benchmark series between start_date and end_date
plot_strategy_last_return() Horizontal bar chart of each strategy's return over the period, with the benchmark and strategy mean marked
plot_strategy_creturn() Cumulative return of each strategy over the period, with the benchmark
from finlab import data
from finlab.plot import StrategyReturnStats

sp500 = data.get('world_index:adj_close')['^GSPC']

stats = StrategyReturnStats('2025-01-01', '2025-12-31', benchmark_return=sp500)
stats.plot_strategy_last_return().show()
stats.plot_strategy_creturn().show()

FAQ

The snippets below reuse symbol and prices from the plot_candles() example.

Q: Charts are not displaying, what should I do?

# Cause 1: Forgot to call .show()
fig = plot_candles(symbol, **prices)
# Not displayed

fig = plot_candles(symbol, **prices)
fig.show()  # Correct

# Cause 2: Missing plotly package
# Solution: pip install plotly

# Cause 3: Jupyter Notebook environment issue
# Add at the beginning of the notebook:
import plotly.io as pio

pio.renderers.default = 'notebook'

Q: How do I export charts as images?

fig = plot_candles(symbol, **prices, recent_days=200)

# Export as HTML (interactive)
fig.write_html('chart.html')

For a PNG, install Kaleido (pip install kaleido, which also needs a Chrome browser) and call fig.write_image('chart.png', width=1200, height=800).

Q: How do I customize chart styles?

fig = plot_candles(symbol, **prices, recent_days=200)

# Change title
fig.update_layout(title='Apple Price Trend')

# Change color theme
fig.update_layout(template='plotly_dark')  # Dark theme

# Adjust chart size
fig.update_layout(width=1200, height=600)

fig.show()

Q: Which datasets can the radar chart compare?

Any dataset key whose rows hold one value per symbol works, such as the us_ratios:* and us_key_metrics:* snapshot fields:

from finlab import data

data.search('margin', market='us')  # Find US margin fields

Q: Radar chart shows large value differences, what can I do?

Values are already converted to rank levels, so metrics with different units are comparable. Use cut_bins to change how many levels there are:

plot_tw_stock_radar(
    portfolio=['AAPL', 'MSFT'],
    feats=[
        'us_ratios:gross_profit_margin',
        'us_key_metrics:return_on_equity',
        'us_ratios:debt_to_equity_ratio',
    ],
    cut_bins=10,  # Split all metrics into 10 levels
).show()

Resources