A Python library designed for creating Blockworks Research branded data visualizations using Plotly and interactive tables using AG-Grid within a Streamlit environment.
- Consistent Styling: Automatically applies Blockworks Research branding (colors, fonts, layout) to visualizations.
- Multiple Chart Types (via
BWRPlots
class):- Scatter/Line Plots (
scatter_plot
): Single or dual Y-axis. - Metric Share Area Plots (
metric_share_area_plot
): Normalized stacked area for showing percentage shares over time. Supports data smoothing. - Bar Charts (
bar_chart
): Simple vertical bars for categorical data. - Grouped Bar Charts (
multi_bar
): Compares values across categories for multiple series. Supportstick_frequency
for X-axis labels. - Stacked Bar Charts (
stacked_bar_chart
): Shows parts of a whole across categories or time. Supportssort_descending
for legend/stack order. - Horizontal Bar Charts (
horizontal_bar
): Useful for ranked categories, supports positive/negative values andsort_ascending
. - Plotly Tables (
table_plot
): Renders data as a static, styled table using Plotly's native table trace.
- Scatter/Line Plots (
- Interactive Tables (via
render_aggrid_table
function):- Leverages
streamlit-aggrid
to display Pandas DataFrames in Streamlit apps. - Provides sorting, filtering, pagination, and customization options.
- (Note: Requires a Streamlit environment)
- Leverages
- Data Handling:
- Automatic Y-axis value scaling and suffixing (e.g., K, M, B).
- Intelligent axis range calculation.
- Key parameter
xaxis_is_date
for time-series vs. categorical X-axis behavior in relevant plots. - Utility function
round_and_align_dates
for time-series data preparation.
- Customization:
- Override default styles by passing a configuration dictionary during
BWRPlots
initialization. - Control plot appearance via function parameters (titles, sources, prefixes, suffixes,
x_axis_title
,y_axis_title
, etc.). - Configurable background image for plots (via
general.background_image_path
andplot_specific.<type>.use_background_image
in config).
- Override default styles by passing a configuration dictionary during
- Output Options:
- Save plots as interactive HTML files (
save_image=True
). - Optionally open plots directly in the browser (
open_in_browser=True
).
- Save plots as interactive HTML files (
- Watermark: Easily add a configurable SVG watermark (via
watermark
section in config).
# Using pip
pip install bwr-plots
# Using Poetry
poetry add bwr-plots
import pandas as pd
from bwr_plots import BWRPlots
# 1. Prepare your data (Example: Time series)
dates = pd.date_range(start='2023-01-01', end='2023-06-30', freq='D')
data = pd.DataFrame({
'Metric A': range(len(dates)),
'Metric B': [x * 1.5 + 10 for x in range(len(dates))]
}, index=dates)
# 2. Initialize the plotter
# plotter = BWRPlots() # Use default config
# Or with custom config (see Customization section)
custom_cfg = {"watermark": {"default_use": False}}
plotter = BWRPlots(config=custom_cfg)
# 3. Create a plot
fig_scatter = plotter.scatter_plot(
data=data, # Can be DataFrame or Series
title="Metric Performance Over Time",
subtitle="Comparing Metric A and Metric B",
source="Source: Internal Data",
prefix="$", # Optional: Add prefix to Y-axis ticks
# suffix="%", # Optional: Add suffix to Y-axis ticks
save_image=True, # Saves HTML to ./output/ by default
save_path="my_charts/", # Optional: Specify output directory
open_in_browser=False # Optional: Prevent auto-opening
)
# fig_scatter is a Plotly Figure object, you can further customize it if needed
# fig_scatter.update_layout(...)
# fig_scatter.show() # Display interactively if needed
# Other plot types:
# fig_area = plotter.metric_share_area_plot(data=df_shares, smoothing_window=7, ...)
# fig_bar = plotter.bar_chart(data=series_or_df, ...)
# fig_hbar = plotter.horizontal_bar(data=df_ranked, y_column='Category', x_column='Value', ...)
# fig_multi = plotter.multi_bar(data=df_monthly, tick_frequency=2, ...)
# fig_stacked = plotter.stacked_bar_chart(data=df_monthly_shares, sort_descending=True, ...)
# fig_plotly_table = plotter.table_plot(data=df_simple_table, ...)
This function is designed to be used within a Streamlit application (.py
file run with streamlit run your_script.py
).
# In your Streamlit script (e.g., app.py)
import streamlit as st
import pandas as pd
import numpy as np
from bwr_plots.aggrid_table import render_aggrid_table # Note the direct import
st.set_page_config(layout="wide")
# 1. Prepare your DataFrame
data = {
'col1': ['A', 'B', 'C', 'D'],
'col2': [10, 25, 5, 30],
'col3': np.random.rand(4) * 100
}
df = pd.DataFrame(data)
st.title("My Data Table")
# 2. Render the table
grid_response = render_aggrid_table(
df=df,
title="Data Overview",
subtitle="Key metrics summary",
source="Generated Data",
# Optional: Override AG-Grid settings
# grid_options_override={'paginationPageSize': 5},
# aggrid_params_override={'height': 300}
)
# grid_response contains information about the grid state (selected rows, etc.)
# selected_data = grid_response['selected_rows']
# st.write("Selected:")
# st.dataframe(selected_data)
- Scatter/Line:
plotter.scatter_plot(data, ...)
- Metric Share Area:
plotter.metric_share_area_plot(data, ...)
- Bar Chart:
plotter.bar_chart(data, ...)
- Horizontal Bar:
plotter.horizontal_bar(data, y_column, x_column, ...)
- Grouped Bar (Time Series / Categorical):
plotter.multi_bar(data, ...)
- Stacked Bar (Time Series / Categorical):
plotter.stacked_bar_chart(data, ...)
- Plotly Table:
plotter.table_plot(data, ...)
- Interactive Table (Streamlit):
render_aggrid_table(df, ...)
(Import separately)
Modify the default appearance by passing a custom dictionary matching the structure in src/bwr_plots/config.py
when creating the BWRPlots
instance.
custom_config = {
"colors": {
"background_color": "#F0F0F0",
"primary": "#007ACC", # Affects default bar colors
"default_palette": ["#007ACC", "#FF8C00", "#32CD32", "#DC143C"] # New color cycle
},
"fonts": {
"normal_family": "Arial, sans-serif",
"title": {"size": 40, "color": "#333333"},
"tick": {"size": 18, "color": "#555555"}
},
"watermark": {
"default_path": "assets/my_logo.svg", # Path relative to project root
"default_use": True,
"chart_opacity": 0.8 # Opacity for chart watermark
},
"general": {
"background_image_path": "brand-assets/my_background.png", # Path relative to project root
},
"layout": {
"margin_l": 100 # Adjust left margin
},
"plot_specific": {
"scatter": {
"line_width": 3.0, # Thinner lines for scatter plots
"use_background_image": True # Enable background for scatter plots
}
}
}
plotter = BWRPlots(config=custom_config)
# Now plots created with this 'plotter' instance will use the custom config.
- Watermark Path: The default watermark path (
brand-assets/bwr_white.svg
) is relative to the project root where the script is run. Ensure the asset is accessible or update thewatermark.default_path
in your custom config. - Background Image Path: The background image path (e.g.,
general.background_image_path
) is also relative to the project root. Ensure the asset is accessible and theplot_specific.<type>.use_background_image
flag isTrue
for the desired plot type. - Output Directory: By default, plots saved via
save_image=True
are placed in an./output/
directory created in the current working directory. Use thesave_path
argument to specify a different location. - Fonts: For best results, install the "Maison Neue" and "Inter" font families on the system where plots are generated or viewed. The library specifies fallbacks, but appearance may vary.
open_in_browser
: Set toTrue
in plotting methods to automatically open the generated HTML file in your default web browser.save_image
: Set toTrue
to save the plot as a standalone.html
file.xaxis_is_date
: For plots likescatter_plot
,metric_share_area_plot
,multi_bar
, andstacked_bar_chart
, this boolean parameter (defaultTrue
) determines if the X-axis should be treated as datetime objects or categorical. Set toFalse
for non-temporal categorical X-axes.
Refer to the Python scripts in the examples/
directory for detailed usage patterns for each visualization type. You can run them individually or use examples/run_all_examples.py
. For a comprehensive interactive demonstration, run the Streamlit application: streamlit run app.py
.
- Python = ^3.10
- pandas >= 2.0.0
- plotly >= 5.10.0
- numpy >= 1.20.0
- streamlit >= 1.4.1 (Required only for
render_aggrid_table
) - streamlit-aggrid == 0.3.4.post3 (Required only for
render_aggrid_table
) - openpyxl (For reading
.xlsx
files if needed) - termcolor (Used in examples/utils)
Copyright (c) Blockworks Research