Files
Danglewood 869cfed125 [Release] openbb-v5.0.0 (#7741)
* merge branch develop with main

* bump desktop version

* fix the merge

* sync Cargo.lock to desktop 2.0.0

* fix cli conftest.py

---------

Co-authored-by: deeleeramone <>
2026-09-29 10:58:44 -07:00

173 lines
5.8 KiB
Markdown
Vendored

# OpenBB Charting
Plotly-based charting for the OpenBB Platform. Installing this package registers a `charting` accessor on every `OBBject` command result and enables the `chart=True` argument on Platform endpoints that have a chart.
## Installation
```bash
pip install openbb-charting
```
To display charts in a native desktop window, install the PyWry extra:
```bash
pip install "openbb-charting[pywry]"
```
On Linux, PyWry requires system WebKit/GTK libraries:
- Debian / Ubuntu / Mint: `sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev`
- Arch / Manjaro: `sudo pacman -S webkit2gtk`
- Fedora: `sudo dnf install gtk3-devel webkit2gtk3-devel`
## Usage
Pass `chart=True` to an endpoint that has a chart, then call `show()` on the result:
```python
from openbb import obb
data = obb.equity.price.historical("AAPL", provider="yfinance", chart=True)
data.show()
```
The same chart is reachable through the `charting` accessor on any result, without `chart=True`:
```python
res = obb.equity.price.historical("AAPL", provider="yfinance")
res.charting.show()
```
### Which commands have a chart
Charts are contributed by the installed extensions. List the registered routes:
```python
from openbb_charting import Charting
Charting.functions()
```
### Technical-analysis overlays — `to_chart`
`to_chart` rebuilds the chart of a time-series (OHLCV) result with indicator overlays. Indicators and their parameters are passed through the `indicators` argument:
```python
res = obb.equity.price.historical("AAPL", provider="yfinance")
res.charting.to_chart(
indicators=dict(
sma=dict(length=[20, 50]),
rsi=dict(length=14),
macd=dict(fast=12, slow=26, signal=9),
)
)
res.show()
```
List every available indicator and its parameters:
```python
res.charting.indicators() # from a result
Charting.indicators() # standalone
```
## Building charts directly from data
The accessor exposes builders that accept a DataFrame or a list of `Data` (such as `OBBject.results`) and return an `OpenBBFigure`. Their input signatures differ; `create_line_chart` and `create_bar_chart` also display the chart by default — pass `render=False` to build it without displaying.
```python
res = obb.equity.price.historical("AAPL", provider="yfinance")
df = res.to_dataframe()
fig = res.charting.create_line_chart(data=res.results, target="close", render=False)
fig = res.charting.create_bar_chart(
data=res.results, x="date", y="volume", render=False
)
fig = res.charting.create_correlation_matrix(data=res.results, method="pearson")
fig = res.charting.create_3d_surface(X=df["open"], Y=df["high"], Z=df["close"])
fig.show()
```
## Adding a chart to a command
Register a charting-view class through the `openbb_charting_extension` entry-point group in your `pyproject.toml`:
```toml
[project.entry-points."openbb_charting_extension"]
my_extension = "openbb_my_extension.my_extension_views:MyExtensionViews"
```
A view method is matched to an endpoint by replacing the route's slashes with underscores: `/equity/price/historical` → `equity_price_historical`, `/technical/ema` → `technical_ema`. Each method receives the command output as `**kwargs` and returns a `tuple[OpenBBFigure, dict[str, Any]]` — the interactive figure plus the JSON content the API serializes.
```python
"""Views for MyExtension."""
from typing import Any
from openbb_charting.charts.price_historical import price_historical
from openbb_charting.core.openbb_figure import OpenBBFigure
class MyExtensionViews:
"""MyExtension Views."""
@staticmethod
def my_extension_price_historical(**kwargs) -> tuple[OpenBBFigure, dict[str, Any]]:
"""My Extension Price Historical Chart."""
return price_historical(**kwargs)
```
The chart is then produced by setting `chart=True` on the command, or via `result.charting.show()`.
## Replacing the engine, hooks, and backend
The Platform interfaces (Python, API, CLI, MCP) do not depend on `openbb-charting` by name; they resolve the active engine from whichever OBBject extension registers the `charting` accessor. Three things are pluggable through entry points alone.
### Replace the engine
Ship an OBBject extension that registers the `charting` accessor:
```toml
[project.entry-points."openbb_obbject_extension"]
my_charting = "openbb_my_charting:ext" # ext = Extension(name="charting")
```
If `openbb-charting` is uninstalled, your engine is used automatically. When both are installed, select one with `system_settings.charting_extension` (or the `OPENBB_CHARTING_EXTENSION` environment variable). An engine must expose the `functions()` classmethod, and `get_backend_class()` to be usable from the CLI.
### Chart lifecycle hooks
Register a `ChartingHook` subclass under the `openbb_charting_hooks` group. Hooks run inside chart creation, so they fire for every interface:
```toml
[project.entry-points."openbb_charting_hooks"]
my_hook = "openbb_my_pkg.hooks:MyHook"
```
```python
from openbb_core.app.charting import ChartingHook
class MyHook(ChartingHook):
"""Watermark every figure after it is built."""
routes = () # empty matches all routes
priority = 100 # lower runs first
def post_figure(self, context):
context.figure.add_annotation(text="INTERNAL", opacity=0.1)
return context
```
Stages: `resolve_data`, `pre_figure`, `post_figure`, `pre_render`, `post_render`. A hook mutates `context` in place and/or returns a new one.
### Backend override
Swap the rendering backend (PyWry / browser / custom) without replacing the engine, via the `openbb_charting_backend` group:
```toml
[project.entry-points."openbb_charting_backend"]
my_backend = "openbb_my_pkg.backend:MyBackend"
```
A backend is constructed with a single `charting_settings` argument. The override is opt-in: set `system_settings.charting_backend` (or `OPENBB_CHARTING_BACKEND`) to the registered name. Without a selection, the engine keeps its built-in backend.