ScatterChart demos: two-series scatter, custom marker sizes, z-axis color mapping, log-scale axes, click events, dataset-driven series and axis styling.

Scatter Chart

ScatterChart demos: two-series scatter, custom marker sizes, z-axis color mapping, log-scale axes, click events, dataset-driven series and axis styling.


Overview

ScatterChart renders scatter/point charts with optional z-axis color mapping, voronoi-based proximity interaction, and dataset-driven data, wrapping the MUI X Charts scatter chart for Plotly Dash. It is a Community (free) component — no MUI X Pro license required.

from dash_mui_charts import ScatterChart

ScatterChart(
    series=[
        {
            'id': 'group-a',
            'label': 'Group A',
            'data': [{'x': 1, 'y': 5, 'id': 0}, {'x': 2, 'y': 8, 'id': 1}],
            'color': '#1976d2',
            'markerSize': 6,
        },
    ],
    voronoiMaxRadius=30,   # proximity-based hover/click
    height=400,
)

Axes support scaleType including log and sqrt scales; renderer='svg-batch' speeds up large datasets.

MUI X Charts uses seriesId (a string), not seriesIndex, in event payloads like clickData.


Basic scatter — two series

Two data clusters plotted as separate series with grid lines.

# File: docs/scatter/basic_example.py

from dash_mui_charts import ScatterChart

from docs.scatter._data import cluster_a, cluster_b

component = ScatterChart(
    id='scatter-basic',
    height=350,
    series=[
        {
            'id': 'cluster-a',
            'label': 'Cluster A',
            'data': cluster_a,
            'color': '#1976d2',
            'highlightScope': {'highlight': 'series', 'fade': 'global'},
        },
        {
            'id': 'cluster-b',
            'label': 'Cluster B',
            'data': cluster_b,
            'color': '#ff7043',
            'highlightScope': {'highlight': 'series', 'fade': 'global'},
        },
    ],
    grid={'horizontal': True, 'vertical': True},
    xAxis=[{'label': 'X Value'}],
    yAxis=[{'label': 'Y Value', 'width': 50}],
    voronoiMaxRadius=30,
)

:defaultExpanded: false :withExpandedButton: true


Custom marker sizes

Use markerSize (the radius in pixels) to differentiate series — smaller markers for dense data, larger for emphasis.

# File: docs/scatter/sizes_example.py

from dash_mui_charts import ScatterChart

from docs.scatter._data import size_data_large, size_data_small

component = ScatterChart(
    id='scatter-sizes',
    height=300,
    series=[
        {
            'id': 'small-markers',
            'label': 'Background (r=3)',
            'data': size_data_large,
            'color': '#90caf9',
            'markerSize': 3,
        },
        {
            'id': 'large-markers',
            'label': 'Focus Points (r=10)',
            'data': size_data_small,
            'color': '#e53935',
            'markerSize': 10,
            'highlightScope': {'highlight': 'item', 'fade': 'global'},
        },
    ],
    xAxis=[{'label': 'X', 'min': 0, 'max': 100}],
    yAxis=[{'label': 'Y', 'min': 0, 'max': 100, 'width': 40}],
)

:defaultExpanded: false :withExpandedButton: true


Z-axis color mapping

Use zAxis with a colorMap to color scatter points by a third variable (continuous, piecewise, or ordinal). Color priority: z-axis > y-axis > x-axis > series color.

# File: docs/scatter/colormap_example.py

from dash_mui_charts import ScatterChart

from docs.scatter._data import correlated

component = ScatterChart(
    id='scatter-colormap',
    height=400,
    series=[
        {
            'id': 'correlated',
            'label': 'Data Points',
            'data': correlated,
            'markerSize': 5,
        },
    ],
    xAxis=[{
        'label': 'X Value',
        'min': -5,
        'max': 105,
    }],
    yAxis=[{
        'label': 'Y Value (2x + 20 + noise)',
        'width': 60,
        'domainLimit': 'nice',
    }],
    zAxis=[{
        'colorMap': {
            'type': 'continuous',
            'min': 30,
            'max': 300,
            'color': ['#4fc3f7', '#e53935'],
        },
    }],
    grid={'horizontal': True, 'vertical': True},
    voronoiMaxRadius=40,
)

:defaultExpanded: false :withExpandedButton: true


Log scale axis

Scatter charts support logarithmic axis scales for data spanning multiple orders of magnitude.

# File: docs/scatter/log_example.py

from dash_mui_charts import ScatterChart

from docs.scatter._data import log_data_a, log_data_b

component = ScatterChart(
    id='scatter-log',
    height=350,
    series=[
        {
            'id': 'manufacturer-a',
            'label': 'Manufacturer A',
            'data': log_data_a,
            'markerSize': 4,
            'color': '#1565c0',
            'highlightScope': {'highlight': 'series', 'fade': 'global'},
        },
        {
            'id': 'manufacturer-b',
            'label': 'Manufacturer B',
            'data': log_data_b,
            'markerSize': 4,
            'color': '#e65100',
            'highlightScope': {'highlight': 'series', 'fade': 'global'},
        },
    ],
    xAxis=[{
        'label': 'Year',
        'tickLabelStyle': {'fontSize': 11},
    }],
    yAxis=[{
        'scaleType': 'log',
        'label': 'Density (units/mm²)',
        'width': 65,
        'tickLabelStyle': {'fontSize': 11},
    }],
    grid={'horizontal': True},
    voronoiMaxRadius=25,
)

:defaultExpanded: false :withExpandedButton: true


Click events

Click on scatter points to capture event data in Dash callbacks — clickData reports {'type': 'scatter', 'seriesId': ..., 'dataIndex': ..., 'x': ..., 'y': ...}. voronoiMaxRadius controls the interaction distance.

# File: docs/scatter/click_example.py

import json

from dash import Input, Output, callback, html

from dash_mui_charts import ScatterChart

component = html.Div(
    [
        ScatterChart(
            id='scatter-click',
            height=300,
            series=[
                {
                    'id': 'series-a',
                    'label': 'A',
                    'data': [
                        {'x': 1, 'y': 5, 'id': 0},
                        {'x': 2, 'y': 3, 'id': 1},
                        {'x': 3, 'y': 8, 'id': 2},
                        {'x': 4, 'y': 2, 'id': 3},
                        {'x': 5, 'y': 7, 'id': 4},
                        {'x': 6, 'y': 4, 'id': 5},
                        {'x': 7, 'y': 9, 'id': 6},
                        {'x': 8, 'y': 1, 'id': 7},
                    ],
                    'color': '#7e57c2',
                    'markerSize': 8,
                    'highlightScope': {'highlight': 'item'},
                },
                {
                    'id': 'series-b',
                    'label': 'B',
                    'data': [
                        {'x': 1.5, 'y': 6, 'id': 0},
                        {'x': 2.5, 'y': 4, 'id': 1},
                        {'x': 3.5, 'y': 7, 'id': 2},
                        {'x': 4.5, 'y': 3, 'id': 3},
                        {'x': 5.5, 'y': 8, 'id': 4},
                        {'x': 6.5, 'y': 5, 'id': 5},
                        {'x': 7.5, 'y': 6, 'id': 6},
                    ],
                    'color': '#26a69a',
                    'markerSize': 8,
                    'highlightScope': {'highlight': 'item'},
                },
            ],
            grid={'horizontal': True},
            voronoiMaxRadius=50,
        ),
        html.H4("Click Data:", style={'marginTop': '15px'}),
        html.Pre(
            id='scatter-click-output',
            children="Click on a scatter point to see event data",
            style={
                'backgroundColor': '#f5f5f5',
                'padding': '15px',
                'borderRadius': '5px',
                'whiteSpace': 'pre-wrap',
                'fontSize': '12px',
                'overflow': 'auto',
            },
        ),
    ]
)


@callback(
    Output('scatter-click-output', 'children'),
    Input('scatter-click', 'clickData'),
    prevent_initial_call=True
)
def display_scatter_click(click_data):
    if click_data:
        return json.dumps(click_data, indent=2)
    return "Click on a scatter point to see event data"

:defaultExpanded: false :withExpandedButton: true


Dataset-driven scatter

Use the dataset prop with datasetKeys to map columns to x/y axes — useful when data comes from a shared table format.

# File: docs/scatter/dataset_example.py

from dash_mui_charts import ScatterChart

component = ScatterChart(
    id='scatter-dataset',
    height=300,
    dataset=[
        {'x1': 373, 'y1': 434, 'x2': 304, 'y2': 349},
        {'x1': 173, 'y1': 437, 'x2': 208, 'y2': 347},
        {'x1': 68, 'y1': 292, 'x2': 151, 'y2': 280},
        {'x1': 121, 'y1': 116, 'x2': 185, 'y2': 176},
        {'x1': 322, 'y1': 61, 'x2': 278, 'y2': 170},
        {'x1': 466, 'y1': 210, 'x2': 346, 'y2': 246},
        {'x1': 418, 'y1': 403, 'x2': 326, 'y2': 333},
        {'x1': 224, 'y1': 449, 'x2': 235, 'y2': 352},
        {'x1': 87, 'y1': 335, 'x2': 158, 'y2': 311},
        {'x1': 104, 'y1': 167, 'x2': 166, 'y2': 218},
        {'x1': 262, 'y1': 70, 'x2': 251, 'y2': 161},
        {'x1': 421, 'y1': 167, 'x2': 335, 'y2': 199},
        {'x1': 442, 'y1': 352, 'x2': 341, 'y2': 302},
        {'x1': 294, 'y1': 474, 'x2': 264, 'y2': 366},
        {'x1': 101, 'y1': 386, 'x2': 174, 'y2': 318},
    ],
    series=[
        {
            'id': 'ds-a',
            'label': 'Series A',
            'datasetKeys': {'x': 'x1', 'y': 'y1'},
        },
        {
            'id': 'ds-b',
            'label': 'Series B',
            'datasetKeys': {'x': 'x2', 'y': 'y2'},
        },
    ],
    yAxis=[{'label': 'Rainfall (mm)', 'width': 60}],
    grid={'horizontal': True, 'vertical': True},
)

:defaultExpanded: false :withExpandedButton: true


Axis styling

The full axis API: tickLabelStyle, labelStyle, tickSize, tickNumber, domainLimit, disableLine and more.

# File: docs/scatter/axis_styling_example.py

from dash_mui_charts import ScatterChart

from docs.scatter._data import correlated

component = ScatterChart(
    id='scatter-axis-styling',
    height=400,
    series=[
        {
            'id': 'styled',
            'label': 'Measurements',
            'data': correlated[:40],
            'markerSize': 6,
            'color': '#00897b',
            'highlightScope': {'highlight': 'item', 'fade': 'global'},
        },
    ],
    xAxis=[{
        'label': 'Independent Variable',
        'min': -5,
        'max': 105,
        'tickSize': 8,
        'tickNumber': 10,
        'tickLabelStyle': {
            'fontSize': 11,
            'fontWeight': 'bold',
        },
        'labelStyle': {
            'fontSize': 14,
            'fontWeight': 'bold',
            'fill': '#00897b',
        },
        'domainLimit': 'nice',
    }],
    yAxis=[{
        'label': 'Dependent Variable',
        'width': 65,
        'tickSize': 8,
        'tickLabelStyle': {
            'fontSize': 11,
            'fontWeight': 'bold',
        },
        'labelStyle': {
            'fontSize': 14,
            'fontWeight': 'bold',
            'fill': '#00897b',
        },
        'domainLimit': 'nice',
    }],
    grid={'horizontal': True, 'vertical': True},
    margin={'left': 75, 'bottom': 50, 'right': 20, 'top': 20},
    voronoiMaxRadius=40,
)

:defaultExpanded: false :withExpandedButton: true


Related pages


Source: /scatter

Note for AI agents: This is the static, prerendered view of an interactive Dash application served because we detected a non-JS user agent. Full prose docs: