API reference
finlab.plot
On this page7
finlab.plot draws candlestick, radar, treemap, river and strategy charts with plotly. Every plotting function returns a plotly.graph_objects.Figure: call .show() to display it, or use plotly methods to customize it. plot_candles() draws from any price series, so it works for US stocks, and 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.
Which function to use
| You want to | Use |
|---|---|
| Draw a candlestick chart with indicators from your own price series | plot_candles() |
| Draw a candlestick chart for a Taiwan stock | plot_tw_stock_candles() (Taiwan only) |
| Compare several stocks' financial metrics | plot_tw_stock_radar() |
| Compare your cloud strategies' returns with a benchmark | StrategyReturnStats |
| See how your cloud strategies' holdings are spread | StrategySunburst (Taiwan only) |
| Show the whole market by industry, sized and colored by two metrics | plot_tw_stock_treemap() (Taiwan only) |
| Add your own metric to that treemap | create_treemap_data() (Taiwan only) |
| See where a stock's P/E or P/B sits in its range | plot_tw_stock_river() (Taiwan only) |
All of these need the plotly package (pip install plotly).
Draw candlestick charts
plot_candles()
Draws 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.
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()| Parameter | Type | Default | Description |
|---|---|---|---|
symbol | str | required | 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 | required | Date-indexed price and volume series of one symbol. |
recent_days | int | 250 | Number of most recent rows to plot. |
resample | str | 'D' | Candle period: 'D' daily, 'W' weekly, 'M' monthly. |
overlay_func | dict or list[dict] | None | Lines drawn on the price panel, {name: indicator}. None uses Bollinger Bands from data.indicator('BBANDS'). |
technical_func | dict or list[dict] | None | Indicator subplots; each dict is one subplot. None uses the KD indicator from data.indicator('STOCH'). |
Returns a plotly.graph_objects.Figure.
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)'; TA-Lib function names require the ta-lib package.
To choose your own overlay lines and subplots:
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.
plot_tw_stock_candles()
Draws a candlestick chart for a Taiwan stock: it loads the stock's prices and volume, then calls plot_candles(). It reads Taiwan price datasets, so for US stocks use plot_candles() with US price series.
from finlab.plot import plot_tw_stock_candles
plot_tw_stock_candles('2330', recent_days=200).show()| Parameter | Type | Default | Description |
|---|---|---|---|
symbol | str | required | Taiwan stock code. stock_id is accepted as an alias. |
recent_days | int | 400 | Number of most recent trading days to plot. |
adjust_price | bool | False | Use adjusted prices. |
resample | str | 'D' | Candle period: 'D' daily, 'W' weekly, 'M' monthly. |
overlay_func | dict or list[dict] | None | Lines on the price panel. None uses Bollinger Bands. |
technical_func | dict or list[dict] | None | Indicator subplots. None uses one KD subplot. |
Returns a plotly.graph_objects.Figure, the candlestick chart.
Compare financial metrics
plot_tw_stock_radar()
Compares 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.
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.
| Parameter | Type | Default | Description |
|---|---|---|---|
portfolio | list[str] | required | Symbols to compare, e.g. ['AAPL', 'MSFT']. |
feats | list[str] | None | FinLab dataset keys to compare. None uses 18 Taiwan financial metrics, so pass feats for other markets. Axis names are the part of each key after :. |
mode | str | 'line_polar' | 'line_polar', 'bar_polar' or 'scatter_polar' (see plotly express). |
line_polar_fill | str | None | Fill for 'line_polar': None, 'toself' (close each trace into a shape) or 'tonext' (fill between consecutive traces). |
period | str | None | Row label of the datasets to compare. None uses the latest row. |
cut_bins | int | 10 | Number of rank levels. |
title | str | None | Chart title. |
custom_data | pd.DataFrame | None | Your own rank levels: index of symbols, one column per metric. Replaces feats. |
Returns a plotly.graph_objects.Figure, or None (with an error log) when none of the symbols has data.
Which mode to pick:
'bar_polar': bar polar chart, recommended for comparing 2 to 5 stocks.'line_polar': line polar chart, suited to one stock across many metrics.'scatter_polar': scatter polar chart, suited to viewing the raw data points.
Monitor your cloud strategies
Both classes read the strategies you uploaded to FinLab cloud, so sign in with finlab.login() first.
StrategyReturnStats()
Compares the returns of your uploaded strategies with a benchmark over a period.
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()| Parameter | Type | Default | Description |
|---|---|---|---|
start_date | str | required | Start date of the return calculation. |
end_date | str | required | End date of the return calculation. |
strategy_names | list[str] | None | Names of your own strategies to include. None includes all uploaded strategies. |
benchmark_return | pd.Series | None | Benchmark price series. None uses the Taiwan weighted return index, so pass one for US strategies. |
stats.get_benchmark_return()
Returns the benchmark series between start_date and end_date, as a pd.Series.
stats.get_benchmark_return()stats.plot_strategy_last_return()
Draws a horizontal bar chart of each strategy's return over the period, with the benchmark and the strategy mean marked.
stats.plot_strategy_last_return().show()stats.plot_strategy_creturn()
Draws the cumulative return of each strategy over the period, with the benchmark.
stats.plot_strategy_creturn().show()StrategySunburst()
Taiwan market only: draws a sunburst chart of the holdings of your strategies uploaded to FinLab cloud, for monitoring several strategies at once. 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 US strategies.
from finlab.plot import StrategySunburst
strategies = StrategySunburst()
strategies.plot().show()It takes no parameters.
strategies.get_strategy_df()
Returns the combined holdings after applying strategy weights.
strategies.get_strategy_df({'US Momentum': 0.6, 'Quality Value': 0.4})| Parameter | Type | Default | Description |
|---|---|---|---|
select_strategy | dict | None | Strategy names and their capital weights, e.g. {'US Momentum': 0.6, 'Quality Value': 0.4}. None takes all strategies, equally weighted. |
Returns a pd.DataFrame of holdings, or None when you have no strategies.
strategies.plot()
Draws the holdings sunburst.
# Show which strategies hold each position
strategies.plot(path=['market', 'category', 'stock_id', 's_name']).show()| Parameter | Type | Default | Description |
|---|---|---|---|
select_strategy | dict | None | Strategy names and weights, as in get_strategy_df(). |
path | list[str] | None | Rings from inside to outside. None uses ['s_name', 'market', 'category', 'stock_id']; ['market', 'category', 'stock_id', 's_name'] shows which strategies hold each position. |
color_continuous_scale | str | 'RdBu_r' | Name of a plotly color scale. |
Returns a plotly.graph_objects.Figure, the holdings sunburst.
Taiwan market charts
These helpers read Taiwan company and valuation data, so they work for the Taiwan market only.
plot_tw_stock_treemap()
Draws a nested treemap of Taiwan stocks grouped by market and industry; block area and color show two metrics at once.
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()| Parameter | Type | Default | Description |
|---|---|---|---|
start, end | str | None | Date range, e.g. '2024-01-02' and '2024-01-31'. Both must be trading days. |
area_ind | str | 'market_value' | Metric for block area: 'market_value' or 'turnover' (trading value over the period). |
item | str | 'return_ratio' | 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 | None | Clip item to (lower, upper) so extreme values do not flatten the color scale (see DataFrame.clip). |
color_continuous_scale | str | 'Temps' | Name of a plotly color scale. |
treemap_data | pd.DataFrame | None | Custom data in the format returned by create_treemap_data(). |
Returns a plotly.graph_objects.Figure, or None when the data or area_ind is unavailable. return_ratio is the return between the two days, so setting start and end to the same day makes every block 0.
Common combinations:
- Market heat:
area_ind='market_value',item='return_ratio' - Trading activity:
area_ind='turnover',item='return_ratio'
create_treemap_data()
Builds 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=...).
from finlab.plot import create_treemap_data, plot_tw_stock_treemap
treemap = create_treemap_data(start='2024-01-02', end='2024-01-31', item='return_ratio')
print(treemap.head())
plot_tw_stock_treemap(treemap_data=treemap).show()| Parameter | Type | Default | Description |
|---|---|---|---|
start, end | str | required | Date range. |
item | str | 'return_ratio' | 'return_ratio' or a FinLab dataset key whose latest value in the range is added. |
clip | tuple | None | Clip item to (lower, upper). |
Returns a pd.DataFrame, or None if item has no data in the range.
plot_tw_stock_river()
Draws 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.
from finlab.plot import plot_tw_stock_river
plot_tw_stock_river(
stock_id='2330',
start='2015-01-01',
end='2024-01-01',
mode='pe',
split_range=10,
).show()| Parameter | Type | Default | Description |
|---|---|---|---|
symbol | str | '2330' | Taiwan stock code (pass the stock you want; the default is a sample code). stock_id is accepted as an alias. |
start, end | str | None | Date range, e.g. '2020-01-02' and '2024-01-05'. None uses all data. |
mode | str | 'pe' | 'pe' (price-to-earnings) or 'pb' (price-to-book). |
split_range | int | 8 | Number of bands; more bands give finer color levels. |
Returns a plotly.graph_objects.Figure, or None when the mode or symbol is invalid. It needs a long enough history (at least 2 years is recommended), and because financial statements are published with a delay, the latest quarter may have no data yet.
Common questions
The snippets below reuse symbol and prices from the plot_candles() example.
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'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).
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()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 fieldsThe radar chart's metrics have very different ranges, 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()Next steps
- Data visualization Full examples of every chart and what they look like.
- finlab.report The performance charts built into a backtest report.
- Technical indicators Compute the indicators to draw on a candlestick chart with
data.indicator().
For advanced styling, see the Plotly documentation.
Was this page helpful?