Altair 散点图添加不需要的线条

Altair Scatterplot adds unwanted lines

当在热图上方分层时,Altair 散点图似乎仅在点值也在热图的轴上时才有效。在任何其他情况下,都会添加沿 x 和 y 值的白线。这是一个最小的例子:

import streamlit as st
import altair as alt
import numpy as np
import pandas as pd

# Compute x^2 + y^2 across a 2D grid
x, y = np.meshgrid(range(-5, 5), range(-5, 5))
z = x ** 2 + y ** 2

# Convert this grid to columnar data expected by Altair
source = pd.DataFrame({'x': x.ravel(),
                     'y': y.ravel(),
                     'z': z.ravel()})

c = alt.Chart(source).mark_rect().encode(
    x='x:O',
    y='y:O',
    color='z:Q'
)

scatter_source = pd.DataFrame({'x': [-1.001,-3], 'y': [0,1]})
s = alt.Chart(scatter_source).mark_circle(size=100).encode(
x='x:O',
y='y:O')

st.altair_chart(c + s)

有什么办法可以防止这种行为吗?我想稍后为这些点设置动画,因此向热图轴添加值不是一个选项。

序数编码(由 :O 标记)将始终创建一个离散轴,每个唯一值一个 bin。听起来您想使用定量编码(由 :Q 标记)可视化您的数据,这会创建一个连续的 real-valued 轴。

不过,在热图的情况下,这会使事情变得复杂:如果您不再将数据视为有序类别,则必须指定沿每个轴的每个 bin 的起点和终点。这需要考虑一下您的垃圾箱代表什么:值“2”是否代表 2 到 3 之间的数字?从 1 到 2?从 1.5 到 2.5?答案将取决于上下文。

这是使用 calculate transform 计算这些 bin 边界的示例,假设这些值代表单位 bin 的中心:

c = alt.Chart(source).transform_calculate(
    x1=alt.datum.x - 0.5,
    x2=alt.datum.x + 0.5,
    y1=alt.datum.y - 0.5,
    y2=alt.datum.y + 0.5,
).mark_rect().encode(
    x='x1:Q', x2='x2:Q',
    y='y1:Q', y2='y2:Q',
    color='z:Q'
).properties(
    width=400, height=400
)

scatter_source = pd.DataFrame({'x': [-1.001,-3], 'y': [0,1]})
s = alt.Chart(scatter_source).mark_circle(size=100).encode(
  x='x:Q',
  y='y:Q'
)

st.altair_chart(c + s)

或者,如果您希望这种分箱更自动地发生,您可以在每个轴上使用分箱变换:

c = alt.Chart(source).mark_rect().encode(
    x=alt.X('x:Q', bin=True),
    y=alt.Y('y:Q', bin=True),
    color='z:Q'
).properties(
    width=400,
    height=400
)

scatter_source = pd.DataFrame({'x': [-1.001,-3], 'y': [0,1]})
s = alt.Chart(scatter_source).mark_circle(size=100).encode(
  x='x:Q',
  y='y:Q'
)