You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Altair图表中条件选择相等性异常问题:交互式房屋友谊分数可视化点击响应故障

Fixing Altair Interactive Friendship Score Visualization

Let's dig into why your code only works when clicking house D, and fix it up properly.

What's Going Wrong?

Your core issues are two-fold:

  1. Data Structure Overload: When you merged the geographic data with the long-format friendship data, you ended up with 16 rows (4 houses × 4 friendship pairs). This means each house's rectangle in your geo chart is actually rendering 4 overlapping data points, which confuses the selection logic.
  2. Condition Logic Mismatch: The datum.selected_val==datum.house2 check was backwards. You want to show the friendship score between the selected house and the current house being rendered, not the other way around.

Corrected Code

Here's the fixed version with clear improvements:

import altair as alt
import pandas as pd

families = ["A", "B", "C", "D"]
# Geographical house locations (cleaned up column name)
df = pd.DataFrame(
    {
        "x": [1, 2, 1, 2],
        "y": [1, 1, 2, 2],
        "house": families,
    }
)
# Friendship data matrix
friendship_df = pd.DataFrame(
    [[0, 1, 2, 3], [1, 0, 2, 3], [2, 2, 0, 1], [3, 3, 1, 0]],
    columns=families
)
friendship_df = friendship_df.set_index(friendship_df.columns)
# Convert to long format with clearer column names
friendship_df_lf = (
    friendship_df.melt(var_name="source_house", value_name="friendship", ignore_index=False)
    .reset_index()
    .rename(columns={"index": "target_house"})
)

# Selection: Pick one house to show friendships for
selector = alt.selection_single(name="SelectedHouse", fields=["house"], empty="none")

# Base geo chart (one row per house, no overlapping data)
base_geo = alt.Chart(df, width=200, height=200).mark_rect(strokeWidth=1, stroke="white")

# Interactive geo chart with dynamic lookup
geo_chart = base_geo.add_selection(selector).encode(
    x=alt.X("x:N"),
    y=alt.Y("y:N"),
    color=alt.condition(
        selector,
        alt.Color(
            "friendship:O",
            scale=alt.Scale(scheme="redyellowblue", domain=[0, 1, 2, 3]),
        ),
        alt.value("grey")
    )
).transform_lookup(
    # Match current house as target, and filter to the selected source house
    lookup="house",
    from_=alt.LookupData(friendship_df_lf, "target_house", ["friendship", "source_house"]),
    on="source_house",
    values=selector.fields
)

# Add house labels
text_chart = base_geo.mark_text().encode(text="house")
tot_chart = geo_chart + text_chart

# Improved score matrix (only shows selected house's row)
score_chart = (
    alt.Chart(friendship_df_lf, width=200, height=200)
    .mark_rect()
    .encode(
        x="source_house:N",
        y="target_house:N",
        color=alt.condition(
            selector,
            alt.Color(
                "friendship:O",
                scale=alt.Scale(scheme="redyellowblue", domain=[0, 1, 2, 3]),
            ),
            alt.value("grey"),
        ),
    )
).transform_filter(
    alt.datum.source_house == selector.house
)

alt.vconcat(tot_chart, score_chart).show()

Key Improvements

  • Cleaner Data Naming: Renamed columns to source_house and target_house so it's obvious which direction the friendship score goes.
  • Single-Row Per House: The geo chart now uses the original 4-row dataset, so each rectangle maps to exactly one house (no overlapping data points).
  • Dynamic Lookup: Instead of merging all data upfront, transform_lookup fetches only the friendship score relevant to the selected house, making the logic more efficient and clear.
  • Matrix Optimization: Added a transform_filter to the score matrix so it only highlights the row for the selected house, making it easier to cross-verify with the geo chart.

Now clicking any house (A, B, C, or D) will correctly update the geo chart to show friendship scores between the selected house and all others, just like the matrix does!

内容的提问来源于stack exchange,提问作者Kaqmak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 03:33:09