了解 mark_line 点叠加和图例之间的交互
Understanding the interaction between mark_line point overlay and legend
我在 mark_line
的 point
属性 和 [=54= 的颜色图例的外观 运行ce 之间的交互中发现了一些不直观的行为].我 运行 在尝试创建一条包含非常大且大部分为 t运行sparent 点的线以增加会触发该线 tooltip
的区域时加入此操作,但无法保留一个可见的 type=gradient
图例。
下面的代码是针对这个问题的MRE,展示了6个案例:使用[False
、True
和自定义OverlayMarkDef
]点属性 以及使用普通和自定义 color
编码。
import pandas as pd
import altair as alt
# create data
df = pd.DataFrame()
df['x_data'] = [0, 1, 2] * 3
df['y2'] = [0] * 3 + [1] * 3 + [2] * 3
# initialize
base = alt.Chart(df)
markdef = alt.OverlayMarkDef(size=1000, opacity=.001)
color_encode = alt.Color(shorthand='y2', legend=alt.Legend(title='custom legend', type='gradient'))
marks = [False, True, markdef]
encodes = ['y2', color_encode]
plots = []
for i, m in enumerate(marks):
for j, c in enumerate(encodes):
plot = base.mark_line(point=m).\
encode(x='x_data', y='y2', color=c, tooltip=['x_data','y2']).\
properties(title=', '.join([['False', 'True', 'markdef'][i], ['plain encoding', 'custom encoding'][j]]))
plots.append(plot)
combined = alt.vconcat(
alt.hconcat(*plots[:2]).resolve_scale(color='independent'),
alt.hconcat(*plots[2:4]).resolve_scale(color='independent'),
alt.hconcat(*plots[4:]).resolve_scale(color='independent')
).resolve_scale(color='independent')
结果图(交互式工具提示按预期工作):
这些图的颜色数据都是相同的,但颜色图例到处都是。在我的真实案例中,首选gradient
(数据是定量且连续的)。
mark_line
上没有 point
,传说是正确的。
- 添加
point=True
将图例转换为 symbol
类型 - 我不确定为什么会这样,因为定量数据的默认图例类型是 gradient
(如图所示在第一行)这是相同的数据 - 但可以通过自定义编码强制返回 gradient
。
- 尝试通过
OverlayMarkDef
创建自定义点,但是会使强制 gradient
颜色条不可见 - 匹配 OverlayMarkDef
的 opacity
。但这不仅仅是图例总是继承 point
的属性的问题,因为 symbol
图例并不试图反映 opacity
.
我希望为自定义 OverlayMarkDef
提供正常的渐变色条,但我也希望对这里发生的事情建立一些直觉。
自 Altair 4.2.0 以来,右下图的透明度问题已得到修复,因此现在所有包含 point
的场合都会将图例更改为 'Ordinal' 而不是 'Quantitative'.
我认为图例被转换为符号而不是渐变的原因是您正在添加填充点并且 fill
通道未设置为定量字段,因此它默认为 ordinal
或 nominal
排序:
plot = base.mark_line().encode(
x='x_data',
y='y2',
color='y2',
)
plot + plot.mark_circle(opacity=1)
mark_point
给出了一个渐变图例,因为它没有填充,如果我们明确地为 mark_circle
设置填充,我们也会得到一个渐变图例(一个用于 fill
,一个用于color
.
plot = base.mark_line().encode(
x='x_data',
y='y2',
color='y2',
fill='y2'
)
plot + plot.mark_circle(opacity=1)
我同意你的看法,这有点出乎意料,如果 point=True
的编码类型设置为与用于行的编码类型相同会更方便。您可能会建议将此作为 VegaLite 中的增强功能,同时报告您无法通过 type='gradient'
.
覆盖图例类型的明显错误。
我在 mark_line
的 point
属性 和 [=54= 的颜色图例的外观 运行ce 之间的交互中发现了一些不直观的行为].我 运行 在尝试创建一条包含非常大且大部分为 t运行sparent 点的线以增加会触发该线 tooltip
的区域时加入此操作,但无法保留一个可见的 type=gradient
图例。
下面的代码是针对这个问题的MRE,展示了6个案例:使用[False
、True
和自定义OverlayMarkDef
]点属性 以及使用普通和自定义 color
编码。
import pandas as pd
import altair as alt
# create data
df = pd.DataFrame()
df['x_data'] = [0, 1, 2] * 3
df['y2'] = [0] * 3 + [1] * 3 + [2] * 3
# initialize
base = alt.Chart(df)
markdef = alt.OverlayMarkDef(size=1000, opacity=.001)
color_encode = alt.Color(shorthand='y2', legend=alt.Legend(title='custom legend', type='gradient'))
marks = [False, True, markdef]
encodes = ['y2', color_encode]
plots = []
for i, m in enumerate(marks):
for j, c in enumerate(encodes):
plot = base.mark_line(point=m).\
encode(x='x_data', y='y2', color=c, tooltip=['x_data','y2']).\
properties(title=', '.join([['False', 'True', 'markdef'][i], ['plain encoding', 'custom encoding'][j]]))
plots.append(plot)
combined = alt.vconcat(
alt.hconcat(*plots[:2]).resolve_scale(color='independent'),
alt.hconcat(*plots[2:4]).resolve_scale(color='independent'),
alt.hconcat(*plots[4:]).resolve_scale(color='independent')
).resolve_scale(color='independent')
结果图(交互式工具提示按预期工作):
这些图的颜色数据都是相同的,但颜色图例到处都是。在我的真实案例中,首选gradient
(数据是定量且连续的)。
mark_line
上没有point
,传说是正确的。- 添加
point=True
将图例转换为symbol
类型 - 我不确定为什么会这样,因为定量数据的默认图例类型是gradient
(如图所示在第一行)这是相同的数据 - 但可以通过自定义编码强制返回gradient
。 - 尝试通过
OverlayMarkDef
创建自定义点,但是会使强制gradient
颜色条不可见 - 匹配OverlayMarkDef
的opacity
。但这不仅仅是图例总是继承point
的属性的问题,因为symbol
图例并不试图反映opacity
.
我希望为自定义 OverlayMarkDef
提供正常的渐变色条,但我也希望对这里发生的事情建立一些直觉。
自 Altair 4.2.0 以来,右下图的透明度问题已得到修复,因此现在所有包含 point
的场合都会将图例更改为 'Ordinal' 而不是 'Quantitative'.
我认为图例被转换为符号而不是渐变的原因是您正在添加填充点并且 fill
通道未设置为定量字段,因此它默认为 ordinal
或 nominal
排序:
plot = base.mark_line().encode(
x='x_data',
y='y2',
color='y2',
)
plot + plot.mark_circle(opacity=1)
mark_point
给出了一个渐变图例,因为它没有填充,如果我们明确地为 mark_circle
设置填充,我们也会得到一个渐变图例(一个用于 fill
,一个用于color
.
plot = base.mark_line().encode(
x='x_data',
y='y2',
color='y2',
fill='y2'
)
plot + plot.mark_circle(opacity=1)
我同意你的看法,这有点出乎意料,如果 point=True
的编码类型设置为与用于行的编码类型相同会更方便。您可能会建议将此作为 VegaLite 中的增强功能,同时报告您无法通过 type='gradient'
.