Skip to content

⬇  Chart annotations

Submitted by Arnaud Miribel

Summary

Add annotations to specific timestamps in your time series in Altair!

Functions

get_annotations_chart

Creates an Altair Chart with annotation markers on the horizontal axis. Useful to highlight certain events on top of another time series Altair Chart. More here https://share.streamlit.io/streamlit/example-app-time-series-annotation/main

Parameters:

Name Type Description Default
annotations Iterable[Tuple]

Iterable of annotations defined by tuples with date and annotation.

required
y float

Height at which the annotation marker should be. Defaults to 0.

0
min_date str

Only annotations older than min_date will be displayed. Defaults to None.

None
max_date str

Only annotations more recent than max_date will be displayed. Defaults to None.

None
marker str

Marker to be used to indicate there is an annotation. Defaults to "⬇".

'⬇'
marker_size float

Size of the marker (font size). Defaults to 20.

20
marker_offset_x float

Horizontal offset. Defaults to 0.

0
market_offset_y float

Vertical offset. Defaults to -10.

-10
marker_align str

Text-align property of the marker ("left", "right", "center"). Defaults to "center".

'center'

Returns:

Type Description
Chart

alt.Chart: Altair Chart with annotation markers on the horizontal axis

Source code in src/streamlit_extras/chart_annotations/__init__.py
@extra
def get_annotations_chart(
    annotations: Iterable[Tuple],
    y: float = 0,
    min_date: str | None = None,
    max_date: str | None = None,
    marker: str = "⬇",
    marker_size: float = 20,
    marker_offset_x: float = 0,
    market_offset_y: float = -10,
    marker_align: str = "center",
) -> alt.Chart:
    """
    Creates an Altair Chart with annotation markers on the horizontal axis.
    Useful to highlight certain events on top of another time series Altair Chart.
    More here https://share.streamlit.io/streamlit/example-app-time-series-annotation/main

    Args:
        annotations (Iterable[Tuple]): Iterable of annotations defined by tuples with date and annotation.
        y (float, optional): Height at which the annotation marker should be. Defaults to 0.
        min_date (str, optional): Only annotations older than min_date will be displayed. Defaults to None.
        max_date (str, optional): Only annotations more recent than max_date will be displayed. Defaults to None.
        marker (str, optional): Marker to be used to indicate there is an annotation. Defaults to "⬇".
        marker_size (float, optional): Size of the marker (font size). Defaults to 20.
        marker_offset_x (float, optional): Horizontal offset. Defaults to 0.
        market_offset_y (float, optional): Vertical offset. Defaults to -10.
        marker_align (str, optional): Text-align property of the marker ("left", "right", "center"). Defaults to "center".

    Returns:
        alt.Chart: Altair Chart with annotation markers on the horizontal axis
    """

    # Make a DataFrame for annotations
    annotations_df = pd.DataFrame(
        annotations,
        columns=["date", "annotation"],
    )

    annotations_df.date = pd.to_datetime(annotations_df.date)
    annotations_df["y"] = y
    if min_date:
        annotations_df = annotations_df[annotations_df.date.gt(min_date)]
    if max_date:
        annotations_df = annotations_df[annotations_df.date.lt(max_date)]

    encode_params = {"x": "date:T", "y": alt.Y("y:Q"), "tooltip": "annotation"}

    if "url" in annotations_df.columns:
        encode_params["href"] = "url"

    annotations_chart = (
        alt.Chart(annotations_df)
        .mark_text(
            size=marker_size,
            text=marker,
            dy=market_offset_y,
            dx=marker_offset_x,
            align=marker_align,
            color="black",
        )
        .encode(**encode_params)
    )

    return annotations_chart

Import:

from streamlit_extras.chart_annotations import get_annotations_chart # (1)!
  1. You should add this to the top of your .py file 🛠

Examples

example

def example() -> None:
    data: pd.DataFrame = get_data()
    chart: alt.TopLevelMixin = get_chart(data=data)

    chart += get_annotations_chart(
        annotations=[
            ("Mar 01, 2008", "Pretty good day for GOOG"),
            ("Dec 01, 2007", "Something's going wrong for GOOG & AAPL"),
            ("Nov 01, 2008", "Market starts again thanks to..."),
            ("Dec 01, 2009", "Small crash for GOOG after..."),
        ],
    )

    st.altair_chart(chart, use_container_width=True)  # type: ignore
Output (beta)