Skip to main content

Plotly Charts

Basic Plotly Chart

A widget that demonstrates how to use the Plotly library to create a chart. This gives you the ability to create any interactive type of charts with unlimited flexibility.

Basic Plotly Chart Example
@register_widget({
"name": "Plotly Chart",
"description": "Plotly chart",
"type": "chart",
"endpoint": "plotly_chart",
"gridData": {"w": 40, "h": 15}
})

@app.get("/plotly_chart")
def get_plotly_chart():
# Generate mock time series data
mock_data = [
{"date": "2023-01-01", "return": 2.5, "transactions": 1250},
{"date": "2023-01-02", "return": -1.2, "transactions": 1580},
{"date": "2023-01-03", "return": 3.1, "transactions": 1820},
{"date": "2023-01-04", "return": 0.8, "transactions": 1450},
{"date": "2023-01-05", "return": -2.3, "transactions": 1650},
{"date": "2023-01-06", "return": 1.5, "transactions": 1550},
{"date": "2023-01-07", "return": 2.8, "transactions": 1780},
{"date": "2023-01-08", "return": -0.9, "transactions": 1620},
{"date": "2023-01-09", "return": 1.2, "transactions": 1480},
{"date": "2023-01-10", "return": 3.5, "transactions": 1920}
]

dates = [datetime.strptime(d["date"], "%Y-%m-%d") for d in mock_data]
returns = [d["return"] for d in mock_data]
transactions = [d["transactions"] for d in mock_data]

# Create the figure with secondary y-axis
fig = go.Figure()

# Add the line trace for returns
fig.add_trace(go.Scatter(
x=dates,
y=returns,
mode='lines',
name='Returns',
line=dict(width=2)
))

# Add the bar trace for transactions
fig.add_trace(go.Bar(
x=dates,
y=transactions,
name='Transactions',
opacity=0.5
))

# Update layout with axis titles and secondary y-axis
fig.update_layout(
xaxis_title='Date',
yaxis_title='Returns (%)',
yaxis2=dict(
title="Transactions",
overlaying="y",
side="right"
),
legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1
)
)

# Update the bar trace to use secondary y-axis
fig.data[1].update(yaxis="y2")

return json.loads(fig.to_json())

Plotly Chart with Theme

This endpoint extends the basic Plotly chart by adding theme support. The theme parameter is automatically provided by OpenBB Workspace based on the user's current display mode (dark/light). This enables dynamic chart styling that matches the workspace theme. The theme parameter is optional - if unused, OpenBB will still pass it but the endpoint will ignore it.

Note: OpenBB widget UI dark mode is #151518 and light mode is #FFFFFF, using these background colors make the chart look consistent with the widgets in the OpenBB Workspace.

Plotly Chart with Theme Example Plotly Chart with Theme and Toolbar Example
@register_widget({
"name": "Plotly Chart with Theme",
"description": "Plotly chart with theme",
"type": "chart",
"endpoint": "plotly_chart_with_theme",
"gridData": {"w": 40, "h": 15}
})

@app.get("/plotly_chart_with_theme")
def get_plotly_chart_with_theme(theme: str = "dark"):
# Generate mock time series data
mock_data = [
{"date": "2023-01-01", "return": 2.5, "transactions": 1250},
{"date": "2023-01-02", "return": -1.2, "transactions": 1580},
{"date": "2023-01-03", "return": 3.1, "transactions": 1820},
{"date": "2023-01-04", "return": 0.8, "transactions": 1450},
{"date": "2023-01-05", "return": -2.3, "transactions": 1650},
{"date": "2023-01-06", "return": 1.5, "transactions": 1550},
{"date": "2023-01-07", "return": 2.8, "transactions": 1780},
{"date": "2023-01-08", "return": -0.9, "transactions": 1620},
{"date": "2023-01-09", "return": 1.2, "transactions": 1480},
{"date": "2023-01-10", "return": 3.5, "transactions": 1920}
]

dates = [datetime.strptime(d["date"], "%Y-%m-%d") for d in mock_data]
returns = [d["return"] for d in mock_data]
transactions = [d["transactions"] for d in mock_data]

# Create the figure with secondary y-axis
fig = go.Figure()

if theme == "dark":
# Dark theme colors and styling
line_color = "#FF8000" # Orange
bar_color = "#2D9BF0" # Blue
text_color = "#FFFFFF" # White
grid_color = "rgba(51, 51, 51, 0.3)"
bg_color = "#151518" # Dark background
else:
# Light theme colors and styling
line_color = "#2E5090" # Navy blue
bar_color = "#00AA44" # Forest green
text_color = "#333333" # Dark gray
grid_color = "rgba(221, 221, 221, 0.3)"
bg_color = "#FFFFFF" # White background

# Add the line trace for returns with theme-specific color
fig.add_trace(go.Scatter(
x=dates,
y=returns,
mode='lines',
name='Returns',
line=dict(width=2, color=line_color)
))

# Add the bar trace for transactions with theme-specific color
fig.add_trace(go.Bar(
x=dates,
y=transactions,
name='Transactions',
opacity=0.5,
marker_color=bar_color
))

# Update layout with theme-specific styling
fig.update_layout(
xaxis_title='Date',
yaxis_title='Returns (%)',
yaxis2=dict(
title="Transactions",
overlaying="y",
side="right",
gridcolor=grid_color,
tickfont=dict(color=text_color)
),
legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1,
font=dict(color=text_color)
),
paper_bgcolor=bg_color,
plot_bgcolor=bg_color,
font=dict(color=text_color),
xaxis=dict(
gridcolor=grid_color,
tickfont=dict(color=text_color)
),
yaxis=dict(
gridcolor=grid_color,
tickfont=dict(color=text_color)
)
)

# Update the bar trace to use secondary y-axis
fig.data[1].update(yaxis="y2")

return json.loads(fig.to_json())

Plotly Chart with Theme and Toolbar

This endpoint extends the basic Plotly chart by adding a toolbar to the chart. The toolbar is a set of buttons that allows the user to interact with the chart.

Note: As you can see, all the settings and styling utilized by plotly can be too much boilerplate code, so it is recommended to create a plotly_config.py file and use the functions defined in that file to create the chart.

Plotly Chart with Theme and Toolbar Example
@register_widget({
"name": "Plotly Chart with Theme and Toolbar",
"description": "Plotly chart with Theme and toolbar",
"type": "chart",
"endpoint": "plotly_chart_with_theme_and_toolbar",
"gridData": {"w": 40, "h": 15}
})

@app.get("/plotly_chart_with_theme_and_toolbar")
def get_plotly_chart_with_theme_and_toolbar(theme: str = "dark"):
# Generate mock time series data
mock_data = [
{"date": "2023-01-01", "return": 2.5, "transactions": 1250},
{"date": "2023-01-02", "return": -1.2, "transactions": 1580},
{"date": "2023-01-03", "return": 3.1, "transactions": 1820},
{"date": "2023-01-04", "return": 0.8, "transactions": 1450},
{"date": "2023-01-05", "return": -2.3, "transactions": 1650},
{"date": "2023-01-06", "return": 1.5, "transactions": 1550},
{"date": "2023-01-07", "return": 2.8, "transactions": 1780},
{"date": "2023-01-08", "return": -0.9, "transactions": 1620},
{"date": "2023-01-09", "return": 1.2, "transactions": 1480},
{"date": "2023-01-10", "return": 3.5, "transactions": 1920}
]

dates = [datetime.strptime(d["date"], "%Y-%m-%d") for d in mock_data]
returns = [d["return"] for d in mock_data]
transactions = [d["transactions"] for d in mock_data]

# Create the figure with secondary y-axis
fig = go.Figure()

if theme == "dark":
# Dark theme colors and styling
line_color = "#FF8000" # Orange
bar_color = "#2D9BF0" # Blue
text_color = "#FFFFFF" # White
grid_color = "rgba(51, 51, 51, 0.3)"
bg_color = "#151518" # Dark background
else:
# Light theme colors and styling
line_color = "#2E5090" # Navy blue
bar_color = "#00AA44" # Forest green
text_color = "#333333" # Dark gray
grid_color = "rgba(221, 221, 221, 0.3)"
bg_color = "#FFFFFF" # White background

# Add the line trace for returns with theme-specific color
fig.add_trace(go.Scatter(
x=dates,
y=returns,
mode='lines',
name='Returns',
line=dict(width=2, color=line_color)
))

# Add the bar trace for transactions with theme-specific color
fig.add_trace(go.Bar(
x=dates,
y=transactions,
name='Transactions',
opacity=0.5,
marker_color=bar_color
))

# Update layout with theme-specific styling
fig.update_layout(
xaxis_title='Date',
yaxis_title='Returns (%)',
yaxis2=dict(
title="Transactions",
overlaying="y",
side="right",
gridcolor=grid_color,
tickfont=dict(color=text_color)
),
legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1,
font=dict(color=text_color)
),
paper_bgcolor=bg_color,
plot_bgcolor=bg_color,
font=dict(color=text_color),
xaxis=dict(
gridcolor=grid_color,
tickfont=dict(color=text_color)
),
yaxis=dict(
gridcolor=grid_color,
tickfont=dict(color=text_color)
)
)

# Update the bar trace to use secondary y-axis
fig.data[1].update(yaxis="y2")

# Configure the toolbar and other display settings
toolbar_config = {
'displayModeBar': True,
'responsive': True,
'scrollZoom': True,
'modeBarButtonsToRemove': [
'lasso2d',
'select2d',
'autoScale2d',
'toggleSpikelines',
'hoverClosestCartesian',
'hoverCompareCartesian'
],
'modeBarButtonsToAdd': [
'drawline',
'drawcircle',
'drawrect',
'eraseshape'
],
'doubleClick': 'reset+autosize',
'showTips': True,
'watermark': False,
'staticPlot': False,
'locale': 'en',
'showAxisDragHandles': True,
'showAxisRangeEntryBoxes': True,
'displaylogo': False,
'modeBar': {
'bgcolor': 'rgba(0, 0, 0, 0.1)' if theme == 'light' else 'rgba(255, 255, 255, 0.1)',
'color': text_color,
'activecolor': line_color,
'orientation': 'v',
'yanchor': 'top',
'xanchor': 'right',
'x': 1.05, # Increased spacing from chart
'y': 1,
'opacity': 0, # Start hidden
'hovermode': True, # Show on hover
'hoverdelay': 0, # No delay on hover
'hoverduration': 0 # No delay on hover out
}
}

# Convert figure to JSON and add config
figure_json = json.loads(fig.to_json())
figure_json['config'] = toolbar_config

return figure_json

Plotly Chart with Theme and Config File

This widget demonstrates how to create a chart using the Plotly library and use the config file to minimize the amount of code needed to create the chart.

For reference, here's where this particular plotly_config.py was used: https://github.com/OpenBB-finance/backend-examples-for-openbb-workspace/blob/main/getting-started/reference-backend/plotly_config.py

Plotly Chart with Theme and Config File Example
@register_widget({
"name": "Plotly Chart with Theme and Toolbar using Config File",
"description": "Plotly chart with theme and toolbar using config file",
"type": "chart",
"endpoint": "plotly_chart_with_theme_and_toolbar_using_config_file",
"gridData": {"w": 40, "h": 15}
})

@app.get("/plotly_chart_with_theme_and_toolbar_using_config_file")
def get_plotly_chart_with_theme_and_toolbar_using_config_file(theme: str = "dark"):
# Generate mock time series data
mock_data = [
{"date": "2023-01-01", "return": 2.5, "transactions": 1250},
{"date": "2023-01-02", "return": -1.2, "transactions": 1580},
{"date": "2023-01-03", "return": 3.1, "transactions": 1820},
{"date": "2023-01-04", "return": 0.8, "transactions": 1450},
{"date": "2023-01-05", "return": -2.3, "transactions": 1650},
{"date": "2023-01-06", "return": 1.5, "transactions": 1550},
{"date": "2023-01-07", "return": 2.8, "transactions": 1780},
{"date": "2023-01-08", "return": -0.9, "transactions": 1620},
{"date": "2023-01-09", "return": 1.2, "transactions": 1480},
{"date": "2023-01-10", "return": 3.5, "transactions": 1920}
]

dates = [datetime.strptime(d["date"], "%Y-%m-%d") for d in mock_data]
returns = [d["return"] for d in mock_data]
transactions = [d["transactions"] for d in mock_data]

# Get theme colors
colors = get_theme_colors(theme)

# Create the figure
fig = go.Figure()

# Add the line trace for returns
fig.add_trace(go.Scatter(
x=dates,
y=returns,
mode='lines',
name='Returns',
line=dict(width=2, color=colors["main_line"])
))

# Add the bar trace for transactions
fig.add_trace(go.Bar(
x=dates,
y=transactions,
name='Transactions',
opacity=0.5,
marker_color=colors["neutral"]
))

fig.update_layout(**base_layout(theme=theme))

# Add secondary y-axis for transactions
fig.update_layout(
yaxis2=dict(
title="Transactions",
overlaying="y",
side="right",
gridcolor=colors["grid"],
tickfont=dict(color=colors["text"])
)
)

# Update the bar trace to use secondary y-axis
fig.data[1].update(yaxis="y2")

figure_json = json.loads(fig.to_json())
figure_json['config'] = get_toolbar_config()

return figure_json

Plotly Heatmap

This widget demonstrates that with Plotly you can create any type of chart including heatmaps, scatter plots, line charts, 3d charts, etc. and also demonstrates how parameters can influence a plotly chart.

Note that the theme parameter always comes at the end of the function.

Plotly Heatmap Example
@register_widget({
"name": "Plotly Heatmap",
"description": "Plotly heatmap",
"type": "chart",
"endpoint": "plotly_heatmap",
"gridData": {"w": 40, "h": 15},
"params": [
{
"paramName": "color_scale",
"description": "Select the color scale for the heatmap",
"value": "RdBu_r",
"label": "Color Scale",
"type": "text",
"show": True,
"options": [
{"label": "Red-Blue (RdBu_r)", "value": "RdBu_r"},
{"label": "Viridis", "value": "Viridis"},
{"label": "Plasma", "value": "Plasma"},
{"label": "Inferno", "value": "Inferno"},
{"label": "Magma", "value": "Magma"},
{"label": "Greens", "value": "Greens"},
{"label": "Blues", "value": "Blues"},
{"label": "Reds", "value": "Reds"}
]
}
]
})
@app.get("/plotly_heatmap")
def get_plotly_heatmap(color_scale: str = "RdBu_r", theme: str = "dark"):
# Create mock stock symbols
symbols = ['AAPL', 'MSFT', 'GOOGL', 'AMZN', 'TSLA']

# Create mock correlation matrix directly
corr_matrix = [
[1.00, 0.65, 0.45, 0.30, 0.20], # AAPL correlations
[0.65, 1.00, 0.55, 0.40, 0.25], # MSFT correlations
[0.45, 0.55, 1.00, 0.35, 0.15], # GOOGL correlations
[0.30, 0.40, 0.35, 1.00, 0.10], # AMZN correlations
[0.20, 0.25, 0.15, 0.10, 1.00] # TSLA correlations
]

# Get theme colors
colors = get_theme_colors(theme)

# Create the figure
fig = go.Figure()
# Apply base layout configuration
layout_config = base_layout(theme=theme)

# This allows users to modify the layout configuration further
# in case they want to steer from the default settings.
layout_config['title'] = {
'text': "Correlation Matrix",
'x': 0.5,
'y': 0.95,
'xanchor': 'center',
'yanchor': 'top',
'font': {'size': 20}
}
layout_config['margin'] = {'t': 50, 'b': 50, 'l': 50, 'r': 50}

# Update figure with complete layout
fig.update_layout(layout_config)

# Add the heatmap trace
fig.add_trace(go.Heatmap(
z=corr_matrix,
x=symbols,
y=symbols,
colorscale=color_scale,
zmid=colors["heatmap"]["zmid"],
text=[[f'{val:.2f}' for val in row] for row in corr_matrix],
texttemplate='%{text}',
textfont={"color": colors["heatmap"]["text_color"]},
hoverongaps=False,
hovertemplate='%{x} - %{y}<br>Correlation: %{z:.2f}<extra></extra>'
))

# Convert figure to JSON and apply config
figure_json = json.loads(fig.to_json())
figure_json['config'] = {
**get_toolbar_config(),
'scrollZoom': False # Disable scroll zoom
}

return figure_json