跳到主内容
Ctrl+K
本网站适用于版本 5。您可以在此处找到版本 4 的文档。
Vega-Altair 5.5.0 documentation - Home Vega-Altair 5.5.0 documentation - Home

Vega-Altair

  • 入门
  • 用户指南
  • 示例
  • API
    • 发行说明
    • 关于
  • GitHub
  • Stack Overflow
  • 入门
  • 用户指南
  • 示例
  • API
  • 发行说明
  • 关于
  • GitHub
  • Stack Overflow
  • 带有悬停点路径和搜索框的散点图

带有悬停点路径和搜索框的散点图#

本示例结合了横截面分析(比较单一时间点的国家)和纵向分析(跟踪单个国家随时间的变化),使用了受[此 Vega 示例](https://vega.github.io/vega/examples/global-development/)启发的交互式可视化技术。

主要特性:1. 点路径。悬停时,使用轨迹标记显示数据轨迹,轨迹从过去到现在变粗,清晰地指示时间方向。2. 搜索框。实现对国家名称的忽略大小写正则表达式过滤,从而实现动态、灵活的数据点选择,以增强探索性分析。

import altair as alt
from vega_datasets import data

# Data source
source = data.gapminder.url

# X-value slider
x_slider = alt.binding_range(min=1955, max=2005, step=5, name='Year ')
x_select = alt.selection_point(name="x_select", fields=['year'], bind=x_slider, value=1980)

# Hover selection
hover = alt.selection_point(on='mouseover', fields=['country'], empty=False)
# A separate hover for the points since these need empty=True
hover_point_opacity = alt.selection_point(on='mouseover', fields=['country'])

# Search box for country name
search_box = alt.param(
    value='',
    bind=alt.binding(input='search', placeholder="Country", name='Search ')
)

# Base chart
base = alt.Chart(source).encode(
    alt.X('fertility:Q').scale(zero=False).title('Babies per woman (total fertility rate)'),
    alt.Y('life_expect:Q').scale(zero=False).title('Life expectancy'),
    alt.Color('region:N').scale(scheme='dark2').legend(orient='bottom-left', titleFontSize=14, labelFontSize=12).title('Region'),
    alt.Detail('country:N')
).transform_calculate(
    region="""{
        '0': 'South Asia',
        '1': 'Europe & Central Asia',
        '2': 'Sub-Saharan Africa',
        '3': 'The Americas',
        '4': 'East Asia & Pacific',
        '5': 'Middle East & North Africa'
    }[datum.cluster]"""
).transform_filter(
    # Exclude North Korea and South Korea due to source data error
    "datum.country !== 'North Korea' && datum.country !== 'South Korea'"
)

search_matches = alt.expr.test(alt.expr.regexp(search_box, "i"), alt.datum.country)
opacity = (
    alt.when(hover_point_opacity, search_matches)
    .then(alt.value(0.8))
    .otherwise(alt.value(0.1))
)
# Points that are always visible (filtered by slider and search)
visible_points = base.mark_circle(size=100).encode(
    opacity=opacity
    ).transform_filter(
        x_select
    ).add_params(
        hover,
        hover_point_opacity,
        x_select
)

when_hover = alt.when(hover)
hover_line = alt.layer(
    # Line layer
    base.mark_trail().encode(
        alt.Order('year:Q').sort('ascending'),
        alt.Size('year:Q').scale(domain=[1955, 2005], range=[1, 12]).legend(None),
        opacity=when_hover.then(alt.value(0.3)).otherwise(alt.value(0)),
        color=alt.value('#222222')
    ),
    # Point layer
    base.mark_point(size=50).encode(
        opacity=when_hover.then(alt.value(0.8)).otherwise(alt.value(0)),
    )
)

# Year labels
year_labels = base.mark_text(align='left', dx=5, dy=-5, fontSize=14).encode(
    text='year:O',
    color=alt.value('#222222')
).transform_filter(hover)

# Country labels
country_labels = alt.Chart(source).mark_text(
    align='left',
    dx=-15,
    dy=-25,
    fontSize=18,
    fontWeight='bold'
).encode(
    x='fertility:Q',
    y='life_expect:Q',
    text='country:N',
    color=alt.value('black'),
    opacity=when_hover.then(alt.value(1)).otherwise(alt.value(0))
).transform_window(
    rank='rank(life_expect)',
    sort=[alt.SortField('life_expect', order='descending')],
    groupby=['country'] # places label atop highest point on y-axis on hover
).transform_filter(
    alt.datum.rank == 1
).transform_aggregate(
    life_expect='max(life_expect)',
    fertility='max(fertility)',
    groupby=['country']
)

background_year = alt.Chart(source).mark_text(
    baseline='middle',
    fontSize=96,
    opacity=0.2
).encode(
    text='year:O'
).transform_filter(
    x_select
).transform_aggregate(
    year='max(year)'
)

# Combine all layers
chart = alt.layer(
    visible_points, year_labels, country_labels, hover_line, background_year
).properties(
    width=500,
    height=500,
    padding=10  # Padding ensures labels fit
).configure_axis(
    labelFontSize=12,
    titleFontSize=12
).add_params(search_box)

chart
import altair as alt
from vega_datasets import data

# Data source
source = data.gapminder.url

# X-value slider
x_slider = alt.binding_range(min=1955, max=2005, step=5, name='Year ')
x_select = alt.selection_point(name="x_select", fields=['year'], bind=x_slider, value=1980)

# Hover selection
hover = alt.selection_point(on='mouseover', fields=['country'], empty=False)
# A separate hover for the points since these need empty=True
hover_point_opacity = alt.selection_point(on='mouseover', fields=['country'])

# Search box for country name
search_box = alt.param(
    value='',
    bind=alt.binding(input='search', placeholder="Country", name='Search ')
)

# Base chart
base = alt.Chart(source).encode(
    x=alt.X('fertility:Q', scale=alt.Scale(zero=False), title='Babies per woman (total fertility rate)'),
    y=alt.Y('life_expect:Q', scale=alt.Scale(zero=False), title='Life expectancy'),
    color=alt.Color('region:N', title='Region', legend=alt.Legend(orient='bottom-left', titleFontSize=14, labelFontSize=12), scale=alt.Scale(scheme='dark2')),
    detail='country:N'
).transform_calculate(
    region="""{
        '0': 'South Asia',
        '1': 'Europe & Central Asia',
        '2': 'Sub-Saharan Africa',
        '3': 'The Americas',
        '4': 'East Asia & Pacific',
        '5': 'Middle East & North Africa'
    }[datum.cluster]"""
).transform_filter(
    # Exclude North Korea and South Korea due to source data error
    "datum.country !== 'North Korea' && datum.country !== 'South Korea'"
)

search_matches = alt.expr.test(alt.expr.regexp(search_box, "i"), alt.datum.country)
opacity = (
    alt.when(hover_point_opacity, search_matches)
    .then(alt.value(0.8))
    .otherwise(alt.value(0.1))
)
# Points that are always visible (filtered by slider and search)
visible_points = base.mark_circle(size=100).encode(
    opacity=opacity
    ).transform_filter(
        x_select
    ).add_params(
        hover,
        hover_point_opacity,
        x_select
)

when_hover = alt.when(hover)
hover_line = alt.layer(
    # Line layer
    base.mark_trail().encode(
        order=alt.Order(
            'year:Q',
            sort='ascending'
        ),
        size=alt.Size(
            'year:Q',
            scale=alt.Scale(domain=[1955, 2005], range=[1, 12]),
            legend=None
        ),
        opacity=when_hover.then(alt.value(0.3)).otherwise(alt.value(0)),
        color=alt.value('#222222')
    ),
    # Point layer
    base.mark_point(size=50).encode(
        opacity=when_hover.then(alt.value(0.8)).otherwise(alt.value(0)),
    )
)

# Year labels
year_labels = base.mark_text(align='left', dx=5, dy=-5, fontSize=14).encode(
    text='year:O',
    color=alt.value('#222222')
).transform_filter(hover)

# Country labels
country_labels = alt.Chart(source).mark_text(
    align='left',
    dx=-15,
    dy=-25,
    fontSize=18,
    fontWeight='bold'
).encode(
    x='fertility:Q',
    y='life_expect:Q',
    text='country:N',
    color=alt.value('black'),
    opacity=when_hover.then(alt.value(1)).otherwise(alt.value(0))
).transform_window(
    rank='rank(life_expect)',
    sort=[alt.SortField('life_expect', order='descending')],
    groupby=['country'] # places label atop highest point on y-axis on hover
).transform_filter(
    alt.datum.rank == 1
).transform_aggregate(
    life_expect='max(life_expect)',
    fertility='max(fertility)',
    groupby=['country']
)

background_year = alt.Chart(source).mark_text(
    baseline='middle',
    fontSize=96,
    opacity=0.2
).encode(
    text='year:O'
).transform_filter(
    x_select
).transform_aggregate(
    year='max(year)'
)

# Combine all layers
chart = alt.layer(
    visible_points, year_labels, country_labels, hover_line, background_year
).properties(
    width=500,
    height=500,
    padding=10  # Padding ensures labels fit
).configure_axis(
    labelFontSize=12,
    titleFontSize=12
).add_params(search_box)

chart

© 版权所有 2016-2024,Vega-Altair 开发者。

使用 Sphinx 8.1.3 创建。

使用 PyData Sphinx 主题 0.16.0 构建。