Skip to content

Grapher

owid.grapher.Chart

Chart(data: DataFrame)

Create interactive OWID charts from pandas DataFrames.

The Chart class provides a declarative API for building interactive visualizations using OWID's Grapher library. Charts are configured through method chaining and render directly in Jupyter notebooks.

Multiple chart types can be enabled by chaining mark_*() methods. The first one called becomes the default view, or use show() to set a specific default tab.

PARAMETER DESCRIPTION
data

A pandas DataFrame containing the data to visualize. The DataFrame should have columns for time/x-axis, values/y-axis, and optionally entities for grouping.

TYPE: DataFrame

Example
import pandas as pd
from owid.grapher import Chart

df = pd.DataFrame({
    'year': [2020, 2021, 2022],
    'country': ['USA', 'China', 'India'],
    'gdp': [21.4, 14.7, 2.9]
})

# Single chart type
Chart(df).mark_line().encode(
    x='year',
    y='gdp',
    entity='country'
).label(
    title='GDP by Country'
)

# Multiple chart types with bar as default
Chart(df).mark_line().mark_bar().show("discrete-bar").encode(...)
Source code in owid/grapher/__init__.py
def __init__(self, data: pd.DataFrame):
    self.data = data.copy()
    # GrapherState stores all chart configuration
    self._state = GrapherState(
        hideLogo=True,
        hideRelativeToggle=True,
        chartTypes=[],  # Will be populated by mark_*() methods
        xAxis=AxisConfig(),
        yAxis=AxisConfig(),
    )
    self.x: Optional[str] = None
    self.y: Optional[str] = None
    self.y_lower: Optional[str] = None  # Lower bound for confidence intervals
    self.y_upper: Optional[str] = None  # Upper bound for confidence intervals
    self.entity: Optional[str] = None
    self.color: Optional[str] = None
    self.size: Optional[str] = None
    self.time_type = TimeType.YEAR
    self.selection: Optional[List[str]] = None
    self.timespan: Optional[Tuple[Any, Any]] = None
    self.x_unit: Optional[str] = None
    self.y_unit: Optional[str] = None
    self.variable_configs: Dict[str, "VariableConfig"] = {}  # Column metadata

encode

encode(
    x: Optional[str] = None,
    y: Optional[str] = None,
    y_lower: Optional[str] = None,
    y_upper: Optional[str] = None,
    entity: Optional[str] = None,
    color: Optional[str] = None,
    size: Optional[str] = None,
) -> Chart

Map DataFrame columns to visual properties.

This method establishes the visual encoding by mapping DataFrame columns to chart dimensions. The behavior varies by chart type:

  • Line/Bar charts: x is time, y is values, entity groups lines/bars
  • Scatter plots: x and y are both numeric values, entity groups points
PARAMETER DESCRIPTION
x

Column name for x-axis. For line/bar charts, typically a time column ('year', 'date'). For scatter plots, a numeric value column.

TYPE: Optional[str] DEFAULT: None

y

Column name for y-axis values to plot. For bar charts, can be the entity column if you want entities on the y-axis.

TYPE: Optional[str] DEFAULT: None

y_lower

Column name for lower bound of confidence interval. When specified along with y_upper, renders a shaded confidence band around the main line.

TYPE: Optional[str] DEFAULT: None

y_upper

Column name for upper bound of confidence interval. When specified along with y_lower, renders a shaded confidence band around the main line.

TYPE: Optional[str] DEFAULT: None

entity

Column name for grouping data (e.g., 'country', 'region'). Each unique value becomes a separate line/series. Optional for single-series charts.

TYPE: Optional[str] DEFAULT: None

color

Column name for color encoding in scatter plots. Values map to colors.

TYPE: Optional[str] DEFAULT: None

size

Column name for size encoding in scatter plots. Values map to point sizes.

TYPE: Optional[str] DEFAULT: None

RETURNS DESCRIPTION
Chart

Self for method chaining.

RAISES DESCRIPTION
ValueError

If a specified column name is not found in the DataFrame.

Example
# Line chart with multiple countries
Chart(df).mark_line().encode(
    x='year',
    y='population',
    entity='country'
)

# Line chart with confidence intervals
Chart(df).mark_line().encode(
    x='year',
    y='temperature',
    y_lower='temperature_low',
    y_upper='temperature_high',
    entity='region'
)

# Scatter plot with color and size
Chart(df).mark_scatter().encode(
    x='gdp_per_capita',
    y='life_expectancy',
    entity='country',
    color='continent',
    size='population'
)
Source code in owid/grapher/__init__.py
def encode(
    self,
    x: Optional[str] = None,
    y: Optional[str] = None,
    y_lower: Optional[str] = None,
    y_upper: Optional[str] = None,
    entity: Optional[str] = None,
    color: Optional[str] = None,
    size: Optional[str] = None,
) -> "Chart":
    """Map DataFrame columns to visual properties.

    This method establishes the visual encoding by mapping DataFrame columns to
    chart dimensions. The behavior varies by chart type:

    - **Line/Bar charts**: `x` is time, `y` is values, `entity` groups lines/bars
    - **Scatter plots**: `x` and `y` are both numeric values, `entity` groups points

    Args:
        x: Column name for x-axis. For line/bar charts, typically a time column
            ('year', 'date'). For scatter plots, a numeric value column.
        y: Column name for y-axis values to plot. For bar charts, can be the entity
            column if you want entities on the y-axis.
        y_lower: Column name for lower bound of confidence interval. When specified
            along with y_upper, renders a shaded confidence band around the main line.
        y_upper: Column name for upper bound of confidence interval. When specified
            along with y_lower, renders a shaded confidence band around the main line.
        entity: Column name for grouping data (e.g., 'country', 'region'). Each unique
            value becomes a separate line/series. Optional for single-series charts.
        color: Column name for color encoding in scatter plots. Values map to colors.
        size: Column name for size encoding in scatter plots. Values map to point sizes.

    Returns:
        Self for method chaining.

    Raises:
        ValueError: If a specified column name is not found in the DataFrame.

    Example:
        ```python
        # Line chart with multiple countries
        Chart(df).mark_line().encode(
            x='year',
            y='population',
            entity='country'
        )

        # Line chart with confidence intervals
        Chart(df).mark_line().encode(
            x='year',
            y='temperature',
            y_lower='temperature_low',
            y_upper='temperature_high',
            entity='region'
        )

        # Scatter plot with color and size
        Chart(df).mark_scatter().encode(
            x='gdp_per_capita',
            y='life_expectancy',
            entity='country',
            color='continent',
            size='population'
        )
        ```
    """
    self.x = x
    self.y = y
    self.y_lower = y_lower
    self.y_upper = y_upper
    self.entity = entity
    self.color = color
    self.size = size

    # fail early if there's been a typo
    for col in [x, y, y_lower, y_upper, entity, color, size]:
        if col and col not in self.data.columns:
            raise ValueError(f"no such column: {col}")

    if x == "date":
        self.time_type = TimeType.DAY

    self._state.hideLegend = not entity

    return self

label

label(
    title: str = "",
    subtitle: str = "",
    source_desc: str = "",
    note: str = "",
) -> Chart

Add labels and text to the chart.

PARAMETER DESCRIPTION
title

Chart title.

TYPE: str DEFAULT: ''

subtitle

Chart subtitle.

TYPE: str DEFAULT: ''

source_desc

Data source attribution.

TYPE: str DEFAULT: ''

note

Additional notes or footnotes.

TYPE: str DEFAULT: ''

RETURNS DESCRIPTION
Chart

Self for method chaining.

Source code in owid/grapher/__init__.py
def label(
    self, title: str = "", subtitle: str = "", source_desc: str = "", note: str = ""
) -> "Chart":
    """Add labels and text to the chart.

    Args:
        title: Chart title.
        subtitle: Chart subtitle.
        source_desc: Data source attribution.
        note: Additional notes or footnotes.

    Returns:
        Self for method chaining.
    """
    self._state.title = title if title else None
    self._state.subtitle = subtitle if subtitle else None
    self._state.sourceDesc = source_desc if source_desc else None
    self._state.note = note if note else None
    return self

xaxis

xaxis(
    label: Optional[str] = None,
    unit: Optional[str] = None,
    scale: Optional[Literal["linear", "log"]] = None,
    scale_control: Optional[bool] = None,
) -> Chart

Configure the x-axis.

PARAMETER DESCRIPTION
label

Axis label text.

TYPE: Optional[str] DEFAULT: None

unit

Unit of measurement (e.g., '$', 'kg').

TYPE: Optional[str] DEFAULT: None

scale

Scale type ('linear' or 'log').

TYPE: Optional[Literal['linear', 'log']] DEFAULT: None

scale_control

Allow users to toggle scale.

TYPE: Optional[bool] DEFAULT: None

RETURNS DESCRIPTION
Chart

Self for method chaining.

Source code in owid/grapher/__init__.py
def xaxis(
    self,
    label: Optional[str] = None,
    unit: Optional[str] = None,
    scale: Optional[Literal["linear", "log"]] = None,
    scale_control: Optional[bool] = None,
) -> "Chart":
    """Configure the x-axis.

    Args:
        label: Axis label text.
        unit: Unit of measurement (e.g., '$', 'kg').
        scale: Scale type ('linear' or 'log').
        scale_control: Allow users to toggle scale.

    Returns:
        Self for method chaining.
    """
    assert self._state.xAxis is not None  # Initialized in __init__
    if label is not None:
        self._state.xAxis.label = label
    if unit is not None:
        self.x_unit = unit
    if scale is not None:
        self._state.xAxis.scaleType = scale
    if scale_control is not None:
        self._state.xAxis.canChangeScaleType = scale_control
    return self

yaxis

yaxis(
    label: Optional[str] = None,
    unit: Optional[str] = None,
    scale: Optional[Literal["linear", "log"]] = None,
    scale_control: Optional[bool] = None,
) -> Chart

Configure the y-axis.

PARAMETER DESCRIPTION
label

Axis label text.

TYPE: Optional[str] DEFAULT: None

unit

Unit of measurement (e.g., '$', 'kg').

TYPE: Optional[str] DEFAULT: None

scale

Scale type ('linear' or 'log').

TYPE: Optional[Literal['linear', 'log']] DEFAULT: None

scale_control

Allow users to toggle scale.

TYPE: Optional[bool] DEFAULT: None

RETURNS DESCRIPTION
Chart

Self for method chaining.

Source code in owid/grapher/__init__.py
def yaxis(
    self,
    label: Optional[str] = None,
    unit: Optional[str] = None,
    scale: Optional[Literal["linear", "log"]] = None,
    scale_control: Optional[bool] = None,
) -> "Chart":
    """Configure the y-axis.

    Args:
        label: Axis label text.
        unit: Unit of measurement (e.g., '$', 'kg').
        scale: Scale type ('linear' or 'log').
        scale_control: Allow users to toggle scale.

    Returns:
        Self for method chaining.
    """
    assert self._state.yAxis is not None  # Initialized in __init__
    if label is not None:
        self._state.yAxis.label = label
    if unit is not None:
        self.y_unit = unit
    if scale is not None:
        self._state.yAxis.scaleType = scale
    if scale_control is not None:
        self._state.yAxis.canChangeScaleType = scale_control
    return self

axis

axis(
    x_label: Optional[str] = None,
    y_label: Optional[str] = None,
    x_unit: Optional[str] = None,
    y_unit: Optional[str] = None,
    x_scale: Optional[Literal["linear", "log"]] = None,
    y_scale: Optional[Literal["linear", "log"]] = None,
    x_scale_control: Optional[bool] = None,
    y_scale_control: Optional[bool] = None,
) -> Chart

Configure both axes at once.

Convenience method for setting properties on both axes. For single-axis configuration, use xaxis() or yaxis() instead.

PARAMETER DESCRIPTION
x_label

Label text for x-axis.

TYPE: Optional[str] DEFAULT: None

y_label

Label text for y-axis.

TYPE: Optional[str] DEFAULT: None

x_unit

Unit suffix for x-axis values (e.g., '$', '%', 'kg').

TYPE: Optional[str] DEFAULT: None

y_unit

Unit suffix for y-axis values.

TYPE: Optional[str] DEFAULT: None

x_scale

Scale type for x-axis ('linear' or 'log').

TYPE: Optional[Literal['linear', 'log']] DEFAULT: None

y_scale

Scale type for y-axis ('linear' or 'log').

TYPE: Optional[Literal['linear', 'log']] DEFAULT: None

x_scale_control

If True, adds UI control to toggle x-axis scale.

TYPE: Optional[bool] DEFAULT: None

y_scale_control

If True, adds UI control to toggle y-axis scale.

TYPE: Optional[bool] DEFAULT: None

RETURNS DESCRIPTION
Chart

Self for method chaining.

Source code in owid/grapher/__init__.py
def axis(
    self,
    x_label: Optional[str] = None,
    y_label: Optional[str] = None,
    x_unit: Optional[str] = None,
    y_unit: Optional[str] = None,
    x_scale: Optional[Literal["linear", "log"]] = None,
    y_scale: Optional[Literal["linear", "log"]] = None,
    x_scale_control: Optional[bool] = None,
    y_scale_control: Optional[bool] = None,
) -> "Chart":
    """Configure both axes at once.

    Convenience method for setting properties on both axes. For single-axis
    configuration, use xaxis() or yaxis() instead.

    Args:
        x_label: Label text for x-axis.
        y_label: Label text for y-axis.
        x_unit: Unit suffix for x-axis values (e.g., '$', '%', 'kg').
        y_unit: Unit suffix for y-axis values.
        x_scale: Scale type for x-axis ('linear' or 'log').
        y_scale: Scale type for y-axis ('linear' or 'log').
        x_scale_control: If True, adds UI control to toggle x-axis scale.
        y_scale_control: If True, adds UI control to toggle y-axis scale.

    Returns:
        Self for method chaining.
    """
    assert self._state.xAxis is not None  # Initialized in __init__
    assert self._state.yAxis is not None  # Initialized in __init__
    if x_label is not None:
        self._state.xAxis.label = x_label
    if y_label is not None:
        self._state.yAxis.label = y_label
    if x_unit is not None:
        self.x_unit = x_unit
    if y_unit is not None:
        self.y_unit = y_unit
    if x_scale is not None:
        self._state.xAxis.scaleType = x_scale
    if y_scale is not None:
        self._state.yAxis.scaleType = y_scale
    if x_scale_control is not None:
        self._state.xAxis.canChangeScaleType = x_scale_control
    if y_scale_control is not None:
        self._state.yAxis.canChangeScaleType = y_scale_control
    return self

mark_scatter

mark_scatter() -> Chart

Add scatter plot to available chart types.

Scatter plots display individual data points with x and y positions. Use color and size encodings for additional dimensions. Best for showing relationships between two numeric variables.

Can be combined with other mark_*() methods to enable multiple chart types.

RETURNS DESCRIPTION
Chart

Self for method chaining.

Source code in owid/grapher/__init__.py
def mark_scatter(self) -> "Chart":
    """Add scatter plot to available chart types.

    Scatter plots display individual data points with x and y positions. Use `color`
    and `size` encodings for additional dimensions. Best for showing relationships
    between two numeric variables.

    Can be combined with other mark_*() methods to enable multiple chart types.

    Returns:
        Self for method chaining.
    """
    self._add_chart_type("ScatterPlot")
    return self

mark_line

mark_line() -> Chart

Add line chart to available chart types.

Line charts connect data points with lines, ideal for showing trends over time. Multiple entities create multiple lines.

Can be combined with other mark_*() methods to enable multiple chart types.

RETURNS DESCRIPTION
Chart

Self for method chaining.

Source code in owid/grapher/__init__.py
def mark_line(self) -> "Chart":
    """Add line chart to available chart types.

    Line charts connect data points with lines, ideal for showing trends over time.
    Multiple entities create multiple lines.

    Can be combined with other mark_*() methods to enable multiple chart types.

    Returns:
        Self for method chaining.
    """
    self._add_chart_type("LineChart")
    return self

mark_bar

mark_bar(stacked: bool = False) -> Chart

Add bar chart to available chart types.

Bar charts display categorical data with rectangular bars. Bars can be shown side-by-side (default) or stacked on top of each other.

Can be combined with other mark_*() methods to enable multiple chart types.

PARAMETER DESCRIPTION
stacked

If True, creates a stacked bar chart where bars for different entities are stacked vertically. If False (default), bars are shown side-by-side.

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION
Chart

Self for method chaining.

Source code in owid/grapher/__init__.py
def mark_bar(self, stacked: bool = False) -> "Chart":
    """Add bar chart to available chart types.

    Bar charts display categorical data with rectangular bars. Bars can be shown
    side-by-side (default) or stacked on top of each other.

    Can be combined with other mark_*() methods to enable multiple chart types.

    Args:
        stacked: If True, creates a stacked bar chart where bars for different
            entities are stacked vertically. If False (default), bars are shown
            side-by-side.

    Returns:
        Self for method chaining.
    """
    chart_type = "StackedDiscreteBar" if stacked else "DiscreteBar"
    self._add_chart_type(chart_type)
    return self

mark_slope

mark_slope() -> Chart

Add slope chart to available chart types.

Slope charts compare values between two time points, showing the change as connecting lines between start and end values. Ideal for highlighting increases and decreases across entities.

Can be combined with other mark_*() methods to enable multiple chart types.

RETURNS DESCRIPTION
Chart

Self for method chaining.

Source code in owid/grapher/__init__.py
def mark_slope(self) -> "Chart":
    """Add slope chart to available chart types.

    Slope charts compare values between two time points, showing the change
    as connecting lines between start and end values. Ideal for highlighting
    increases and decreases across entities.

    Can be combined with other mark_*() methods to enable multiple chart types.

    Returns:
        Self for method chaining.
    """
    self._add_chart_type("SlopeChart")
    return self

mark_marimekko

mark_marimekko() -> Chart

Add Marimekko chart to available chart types.

Marimekko charts (also called mosaic charts) show part-to-whole relationships where both width and height of segments are meaningful. Width represents one dimension (e.g., population) and height represents another (e.g., percentage).

Can be combined with other mark_*() methods to enable multiple chart types.

RETURNS DESCRIPTION
Chart

Self for method chaining.

Source code in owid/grapher/__init__.py
def mark_marimekko(self) -> "Chart":
    """Add Marimekko chart to available chart types.

    Marimekko charts (also called mosaic charts) show part-to-whole relationships
    where both width and height of segments are meaningful. Width represents one
    dimension (e.g., population) and height represents another (e.g., percentage).

    Can be combined with other mark_*() methods to enable multiple chart types.

    Returns:
        Self for method chaining.
    """
    self._add_chart_type("Marimekko")
    return self

mark_map

mark_map(
    time_tolerance: Optional[int] = None,
    color_scheme: Optional[ColorSchemeName] = None,
    binning_strategy: Optional[BinningStrategy] = None,
    custom_numeric_values: Optional[List[float]] = None,
) -> Chart

Enable the map tab with optional configuration.

Adds a world map visualization showing data geographically. Can be combined with other mark_*() methods.

PARAMETER DESCRIPTION
time_tolerance

How many years to look back/forward for data

TYPE: Optional[int] DEFAULT: None

color_scheme

Color scheme name (e.g., "Reds", "Blues", "YlOrRd")

TYPE: Optional[ColorSchemeName] DEFAULT: None

binning_strategy

How to bin values ("auto", "manual", "equalInterval", "quantiles")

TYPE: Optional[BinningStrategy] DEFAULT: None

custom_numeric_values

Custom bin boundaries when using manual binning

TYPE: Optional[List[float]] DEFAULT: None

RETURNS DESCRIPTION
Chart

Self for method chaining.

Example
# Line chart with map, defaulting to map view
Chart(df).mark_line().mark_map().show("map").encode(...)

# Line chart with customized map
Chart(df).mark_line().mark_map(
    color_scheme='Reds',
    binning_strategy='manual',
    custom_numeric_values=[0, 1000, 10000, 100000]
).encode(...)
Source code in owid/grapher/__init__.py
def mark_map(
    self,
    time_tolerance: Optional[int] = None,
    color_scheme: Optional[ColorSchemeName] = None,
    binning_strategy: Optional[BinningStrategy] = None,
    custom_numeric_values: Optional[List[float]] = None,
) -> "Chart":
    """Enable the map tab with optional configuration.

    Adds a world map visualization showing data geographically. Can be combined
    with other mark_*() methods.

    Args:
        time_tolerance: How many years to look back/forward for data
        color_scheme: Color scheme name (e.g., "Reds", "Blues", "YlOrRd")
        binning_strategy: How to bin values ("auto", "manual", "equalInterval", "quantiles")
        custom_numeric_values: Custom bin boundaries when using manual binning

    Returns:
        Self for method chaining.

    Example:
        ```python
        # Line chart with map, defaulting to map view
        Chart(df).mark_line().mark_map().show("map").encode(...)

        # Line chart with customized map
        Chart(df).mark_line().mark_map(
            color_scheme='Reds',
            binning_strategy='manual',
            custom_numeric_values=[0, 1000, 10000, 100000]
        ).encode(...)
        ```
    """
    self._state.hasMapTab = True

    # Set default tab to map if this is the first mark_*() call
    if self._state.tab == "chart":  # Default value means not yet set
        self._state.tab = "map"

    # Configure map options if any provided
    if any([time_tolerance, color_scheme, binning_strategy, custom_numeric_values]):
        color_scale = ColorScaleConfig(
            baseColorScheme=color_scheme,
            binningStrategy=binning_strategy,
            customNumericValues=custom_numeric_values,
        )
        self._state.map = MapConfig(
            timeTolerance=time_tolerance,
            colorScale=color_scale
            if any([color_scheme, binning_strategy, custom_numeric_values])
            else None,
        )

    return self

show

show(
    tab: Literal[
        "line",
        "discrete-bar",
        "stacked-discrete-bar",
        "scatter",
        "stacked-area",
        "slope",
        "stacked-bar",
        "marimekko",
        "map",
        "table",
    ],
) -> Chart

Set which tab to display by default.

Use this to control which visualization is shown when the chart first loads. The tab must correspond to an enabled chart type (via mark_*() methods).

PARAMETER DESCRIPTION
tab

The tab to show by default. Options: - "line": Line chart - "discrete-bar": Bar chart - "stacked-discrete-bar": Stacked bar chart - "scatter": Scatter plot - "map": World map - "table": Data table

TYPE: Literal['line', 'discrete-bar', 'stacked-discrete-bar', 'scatter', 'stacked-area', 'slope', 'stacked-bar', 'marimekko', 'map', 'table']

RETURNS DESCRIPTION
Chart

Self for method chaining.

Example
# Enable line and bar, but show bar by default
Chart(df).mark_line().mark_bar().show("discrete-bar").encode(...)
Source code in owid/grapher/__init__.py
def show(
    self,
    tab: Literal[
        "line",
        "discrete-bar",
        "stacked-discrete-bar",
        "scatter",
        "stacked-area",
        "slope",
        "stacked-bar",
        "marimekko",
        "map",
        "table",
    ],
) -> "Chart":
    """Set which tab to display by default.

    Use this to control which visualization is shown when the chart first loads.
    The tab must correspond to an enabled chart type (via mark_*() methods).

    Args:
        tab: The tab to show by default. Options:
            - "line": Line chart
            - "discrete-bar": Bar chart
            - "stacked-discrete-bar": Stacked bar chart
            - "scatter": Scatter plot
            - "map": World map
            - "table": Data table

    Returns:
        Self for method chaining.

    Example:
        ```python
        # Enable line and bar, but show bar by default
        Chart(df).mark_line().mark_bar().show("discrete-bar").encode(...)
        ```
    """
    self._state.tab = tab
    return self

interact

interact(
    allow_relative: Optional[bool] = None,
    scale_control: Optional[bool] = None,
    entity_control: Optional[bool] = None,
    entity_mode: Optional[EntitySelectionMode] = None,
) -> Chart

Add interactive controls to the chart.

PARAMETER DESCRIPTION
allow_relative

Show relative/absolute toggle.

TYPE: Optional[bool] DEFAULT: None

scale_control

Show log/linear scale toggle.

TYPE: Optional[bool] DEFAULT: None

entity_control

Show entity/country picker (shorthand for entity_mode).

TYPE: Optional[bool] DEFAULT: None

entity_mode

Entity selection mode. Options: - "add-country": Allow adding multiple entities (default when entity_control=True) - "change-country": Allow only single entity selection (useful for charts with multiple lines per entity, e.g., confidence intervals) - "disabled": Disable entity selection

TYPE: Optional[EntitySelectionMode] DEFAULT: None

RETURNS DESCRIPTION
Chart

Self for method chaining.

Source code in owid/grapher/__init__.py
def interact(
    self,
    allow_relative: Optional[bool] = None,
    scale_control: Optional[bool] = None,
    entity_control: Optional[bool] = None,
    entity_mode: Optional[EntitySelectionMode] = None,
) -> "Chart":
    """Add interactive controls to the chart.

    Args:
        allow_relative: Show relative/absolute toggle.
        scale_control: Show log/linear scale toggle.
        entity_control: Show entity/country picker (shorthand for entity_mode).
        entity_mode: Entity selection mode. Options:
            - "add-country": Allow adding multiple entities (default when entity_control=True)
            - "change-country": Allow only single entity selection (useful for
              charts with multiple lines per entity, e.g., confidence intervals)
            - "disabled": Disable entity selection

    Returns:
        Self for method chaining.
    """
    if allow_relative is not None:
        self._state.hideRelativeToggle = False

    if scale_control is not None:
        # Update yAxis without overwriting existing settings
        assert self._state.yAxis is not None  # Initialized in __init__
        self._state.yAxis.scaleType = "linear"
        self._state.yAxis.canChangeScaleType = scale_control

    if entity_mode is not None:
        self._state.addCountryMode = entity_mode
    elif entity_control is not None:
        self._state.addCountryMode = "add-country" if entity_control else "disabled"

    return self

select

select(
    entities: Optional[List[str]] = None,
    timespan: Optional[Tuple[Any, Any]] = None,
) -> Chart

Pre-select entities and time range.

PARAMETER DESCRIPTION
entities

List of entity names to display.

TYPE: Optional[List[str]] DEFAULT: None

timespan

Tuple of (start, end) for time range.

TYPE: Optional[Tuple[Any, Any]] DEFAULT: None

RETURNS DESCRIPTION
Chart

Self for method chaining.

Source code in owid/grapher/__init__.py
def select(
    self,
    entities: Optional[List[str]] = None,
    timespan: Optional[Tuple[Any, Any]] = None,
) -> "Chart":
    """Pre-select entities and time range.

    Args:
        entities: List of entity names to display.
        timespan: Tuple of (start, end) for time range.

    Returns:
        Self for method chaining.
    """
    if entities:
        self.selection = entities

    if timespan:
        if isinstance(timespan, (str, int)):
            timespan = (timespan, None)
        self.timespan = timespan

    return self

transform

transform(relative: bool) -> Chart

Transform data to relative or absolute values.

Display values as percentage change from a baseline (relative mode) or as absolute values (default). In relative mode, the first time period serves as the baseline (100%).

PARAMETER DESCRIPTION
relative

If True, show values as percentage change from baseline. If False, show absolute values.

TYPE: bool

RETURNS DESCRIPTION
Chart

Self for method chaining.

Source code in owid/grapher/__init__.py
def transform(self, relative: bool) -> "Chart":
    """Transform data to relative or absolute values.

    Display values as percentage change from a baseline (relative mode) or as
    absolute values (default). In relative mode, the first time period serves
    as the baseline (100%).

    Args:
        relative: If True, show values as percentage change from baseline.
            If False, show absolute values.

    Returns:
        Self for method chaining.
    """
    self._state.stackMode = "relative" if relative else "absolute"
    return self

filter

filter(matching_entities_only: bool = True) -> Chart

Filter entities to only show those with complete data.

When enabled, only entities that have data for all time periods and dimensions will be shown. Useful for ensuring fair comparisons by excluding entities with incomplete data.

PARAMETER DESCRIPTION
matching_entities_only

If True, only show entities with complete data across all dimensions and time periods. If False, show all entities even with gaps.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION
Chart

Self for method chaining.

Source code in owid/grapher/__init__.py
def filter(self, matching_entities_only: bool = True) -> "Chart":
    """Filter entities to only show those with complete data.

    When enabled, only entities that have data for all time periods and dimensions
    will be shown. Useful for ensuring fair comparisons by excluding entities with
    incomplete data.

    Args:
        matching_entities_only: If True, only show entities with complete data across
            all dimensions and time periods. If False, show all entities even with gaps.

    Returns:
        Self for method chaining.
    """
    self._state.matchingEntitiesOnly = matching_entities_only
    return self

variable

variable(
    column: str,
    name: Optional[str] = None,
    description_short: Optional[str] = None,
    description_from_producer: Optional[str] = None,
    description_processing: Optional[str] = None,
    description_key: Optional[List[str]] = None,
    unit: Optional[str] = None,
    short_unit: Optional[str] = None,
    color: Optional[str] = None,
    source_name: Optional[str] = None,
    source_link: Optional[str] = None,
) -> Chart

Add rich metadata to a data column/variable.

Configures display properties and documentation for a column that will appear in tooltips, the data table, and source information.

PARAMETER DESCRIPTION
column

Name of the DataFrame column to configure.

TYPE: str

name

Display name (e.g., "Population" instead of "pop").

TYPE: Optional[str] DEFAULT: None

description_short

Brief description shown in tooltips.

TYPE: Optional[str] DEFAULT: None

description_from_producer

Original description from data source.

TYPE: Optional[str] DEFAULT: None

description_processing

How the data was processed/transformed.

TYPE: Optional[str] DEFAULT: None

description_key

List of key points about the variable.

TYPE: Optional[List[str]] DEFAULT: None

unit

Full unit name (e.g., "million people").

TYPE: Optional[str] DEFAULT: None

short_unit

Abbreviated unit for compact display (e.g., "M").

TYPE: Optional[str] DEFAULT: None

color

Hex color for the line/series (e.g., "#ca2628").

TYPE: Optional[str] DEFAULT: None

source_name

Name of the data source.

TYPE: Optional[str] DEFAULT: None

source_link

URL to the data source.

TYPE: Optional[str] DEFAULT: None

RETURNS DESCRIPTION
Chart

Self for method chaining.

Note

The timespan is computed automatically from the data's time column.

Example
Chart(df).mark_line().encode(
    x='year',
    y='population',
    entity='country'
).variable(
    'population',
    name='Population',
    description_short='Total population in millions',
    unit='million people',
    short_unit='M',
    source_name='World Bank',
    source_link='https://data.worldbank.org'
)
Source code in owid/grapher/__init__.py
def variable(
    self,
    column: str,
    name: Optional[str] = None,
    description_short: Optional[str] = None,
    description_from_producer: Optional[str] = None,
    description_processing: Optional[str] = None,
    description_key: Optional[List[str]] = None,
    unit: Optional[str] = None,
    short_unit: Optional[str] = None,
    color: Optional[str] = None,
    source_name: Optional[str] = None,
    source_link: Optional[str] = None,
) -> "Chart":
    """Add rich metadata to a data column/variable.

    Configures display properties and documentation for a column that will
    appear in tooltips, the data table, and source information.

    Args:
        column: Name of the DataFrame column to configure.
        name: Display name (e.g., "Population" instead of "pop").
        description_short: Brief description shown in tooltips.
        description_from_producer: Original description from data source.
        description_processing: How the data was processed/transformed.
        description_key: List of key points about the variable.
        unit: Full unit name (e.g., "million people").
        short_unit: Abbreviated unit for compact display (e.g., "M").
        color: Hex color for the line/series (e.g., "#ca2628").
        source_name: Name of the data source.
        source_link: URL to the data source.

    Returns:
        Self for method chaining.

    Note:
        The timespan is computed automatically from the data's time column.

    Example:
        ```python
        Chart(df).mark_line().encode(
            x='year',
            y='population',
            entity='country'
        ).variable(
            'population',
            name='Population',
            description_short='Total population in millions',
            unit='million people',
            short_unit='M',
            source_name='World Bank',
            source_link='https://data.worldbank.org'
        )
        ```
    """
    self.variable_configs[column] = VariableConfig(
        name=name,
        description_short=description_short,
        description_from_producer=description_from_producer,
        description_processing=description_processing,
        description_key=description_key,
        unit=unit,
        short_unit=short_unit,
        color=color,
        source_name=source_name,
        source_link=source_link,
    )
    return self

export

export() -> Dict[str, Any]

Export the chart as the three components needed for rendering.

RETURNS DESCRIPTION
Dict[str, Any]

Dictionary with keys: - csv_data: CSV string of the data - column_defs: List of column definition dicts for OwidTable - grapher_config: Dict of GrapherState configuration

Source code in owid/grapher/__init__.py
def export(self) -> Dict[str, Any]:
    """Export the chart as the three components needed for rendering.

    Returns:
        Dictionary with keys:
            - csv_data: CSV string of the data
            - column_defs: List of column definition dicts for OwidTable
            - grapher_config: Dict of GrapherState configuration
    """
    (
        df,
        x_col,
        y_cols,
        entity_col,
        color_col,
        year_col,
        selected_entities,
        min_time,
        max_time,
    ) = self._prepare_data()

    return {
        "csv_data": self._build_csv(df),
        "column_defs": self._build_column_defs(y_cols, x_col, year_col),
        "grapher_config": self._build_grapher_config(
            y_cols, x_col, color_col, selected_entities, min_time, max_time
        ),
    }

save_png

save_png(
    path: str,
    include_details: bool = False,
    timeout: int = 30000,
) -> None

Save the chart as a PNG image.

This method uses Playwright to render the chart in a headless browser and export it using the Grapher's built-in rasterize function.

PARAMETER DESCRIPTION
path

File path to save the PNG.

TYPE: str

include_details

Whether to include chart details/sources in export.

TYPE: bool DEFAULT: False

timeout

Timeout in milliseconds for rendering.

TYPE: int DEFAULT: 30000

RAISES DESCRIPTION
ImportError

If Playwright is not installed. Install with: pip install playwright && playwright install chromium

Example
chart = Chart(df).mark_line().encode(x='year', y='population')
chart.save_png("my_chart.png")
Source code in owid/grapher/__init__.py
def save_png(
    self, path: str, include_details: bool = False, timeout: int = 30000
) -> None:
    """Save the chart as a PNG image.

    This method uses Playwright to render the chart in a headless browser
    and export it using the Grapher's built-in rasterize function.

    Args:
        path: File path to save the PNG.
        include_details: Whether to include chart details/sources in export.
        timeout: Timeout in milliseconds for rendering.

    Raises:
        ImportError: If Playwright is not installed. Install with:
            pip install playwright && playwright install chromium

    Example:
        ```python
        chart = Chart(df).mark_line().encode(x='year', y='population')
        chart.save_png("my_chart.png")
        ```
    """
    from owid.grapher.export import save_png

    save_png(self, path, include_details=include_details, timeout=timeout)

save_svg

save_svg(
    path: str,
    include_details: bool = False,
    timeout: int = 30000,
) -> None

Save the chart as an SVG image.

This method uses Playwright to render the chart in a headless browser and export it using the Grapher's built-in rasterize function.

PARAMETER DESCRIPTION
path

File path to save the SVG.

TYPE: str

include_details

Whether to include chart details/sources in export.

TYPE: bool DEFAULT: False

timeout

Timeout in milliseconds for rendering.

TYPE: int DEFAULT: 30000

RAISES DESCRIPTION
ImportError

If Playwright is not installed. Install with: pip install playwright && playwright install chromium

Example
chart = Chart(df).mark_line().encode(x='year', y='population')
chart.save_svg("my_chart.svg")
Source code in owid/grapher/__init__.py
def save_svg(
    self, path: str, include_details: bool = False, timeout: int = 30000
) -> None:
    """Save the chart as an SVG image.

    This method uses Playwright to render the chart in a headless browser
    and export it using the Grapher's built-in rasterize function.

    Args:
        path: File path to save the SVG.
        include_details: Whether to include chart details/sources in export.
        timeout: Timeout in milliseconds for rendering.

    Raises:
        ImportError: If Playwright is not installed. Install with:
            pip install playwright && playwright install chromium

    Example:
        ```python
        chart = Chart(df).mark_line().encode(x='year', y='population')
        chart.save_svg("my_chart.svg")
        ```
    """
    from owid.grapher.export import save_svg

    save_svg(self, path, include_details=include_details, timeout=timeout)

to_html

to_html() -> str

Return the full HTML page for this chart.

This returns a complete HTML document that can be: - Saved to a file and opened in a browser - Embedded in an iframe on a webpage - Used for custom rendering scenarios

RETURNS DESCRIPTION
str

Complete HTML document string.

Example
chart = Chart(df).mark_line().encode(x='year', y='population')

# Save to file
with open("chart.html", "w") as f:
    f.write(chart.to_html())
Source code in owid/grapher/__init__.py
def to_html(self) -> str:
    """Return the full HTML page for this chart.

    This returns a complete HTML document that can be:
    - Saved to a file and opened in a browser
    - Embedded in an iframe on a webpage
    - Used for custom rendering scenarios

    Returns:
        Complete HTML document string.

    Example:
        ```python
        chart = Chart(df).mark_line().encode(x='year', y='population')

        # Save to file
        with open("chart.html", "w") as f:
            f.write(chart.to_html())
        ```
    """
    export = self.export()
    return _generate_chart_html(
        export["csv_data"],
        export["column_defs"],
        export["grapher_config"],
    )

owid.grapher.TimeType

Bases: Enum

Enumeration for time dimension types.

Determines how time values are interpreted and displayed in charts.

ATTRIBUTE DESCRIPTION
DAY

Daily or date-based data. Automatically detected when x='date'. Uses ISO date format (YYYY-MM-DD).

YEAR

Annual data (default). Standard yearly time series.