如何在 Altair 图表中绘制 y 轴带?
How to plot y-axis bands in Altair charts?
Altair 能否在 y 轴上绘制波段,类似于 this Highcharts example?
文档 an example 展示了如何在 y 轴上画一条线,但是将示例改编为使用 plot_rect
来画一个带并不完全奏效:
import altair as alt
from vega_datasets import data
weather = data.seattle_weather.url
chart = alt.Chart(weather).encode(
alt.X("date:T")
)
bars = chart.mark_bar().encode(
y='precipitation:Q'
)
band = chart.mark_rect().encode(
y=alt.value(20),
y2=alt.value(50),
color=alt.value('firebrick')
)
alt.layer(bars, band)
我认为当您使用 alt.value
给出值时的问题是您指定的值是从图表顶部开始的像素值:它没有映射到数据。
在最初的答案中,使用 mark_rule
,它不会创建一个干净的条带,而是创建很多垂直条纹,所以这里有一种正确绘制条带的方法。
第一个解决方案是为波段创建一个全新的数据框,并将其叠加在条形图的顶部:
import altair as alt
import pandas as pd
from vega_datasets import data
weather = data('seattle_weather')
band_df = pd.DataFrame([{'x_min': weather.date.min(),
'x_max': weather.date.max(),
'y_min': 20,
'y_max': 50}])
bars = alt.Chart(weather).mark_bar().encode(
x=alt.X('date:T'),
y=alt.Y('precipitation:Q', title="Precipitation")
)
band_2 = alt.Chart(band_df).mark_rect(color='firebrick', opacity=0.3).encode(
x='x_min:T',
x2='x_max:T',
y='y_min:Q',
y2='y_max:Q'
)
alt.layer(bars, band_2)
第二个选项,如果您不want/cannot创建数据框,则使用transform_calculate
,并在波段图中手动指定x
和x2
:
bars = alt.Chart().mark_bar().encode(
x=alt.X('date:T', title='Date'),
y=alt.Y('precipitation:Q', title="Precipitation")
)
band_3 = alt.Chart().mark_rect(color='firebrick', opacity=0.3).encode(
x='min(date):T',
x2='max(date):T',
y='y_min:Q',
y2='y_max:Q'
).transform_calculate(y_min='20', y_max='50')
alt.layer(bars, band_3, data=data.seattle_weather.url)
初步回答
我会做两件事来模仿您给出的高图示例。首先,使用 transform_calculate
设置 y_min
和 y_max
值。其次,我将使用 mark_rule
以便在 X 轴上有值的区域跨度。 (我还添加了一些不透明度并更改了图层的顺序,以便乐队位于栏杆后面。)
import altair as alt
from vega_datasets import data
weather = data.seattle_weather.url
chart = alt.Chart().encode(
alt.X("date:T")
)
bars = chart.mark_bar().encode(
y='precipitation:Q'
)
band = chart.mark_rule(color='firebrick',
opacity=0.3).encode(
y=alt.Y('y_min:Q'),
y2=alt.Y('y_max:Q')
).transform_calculate(y_min="20",
y_max="50")
alt.layer(band, bars, data=weather)
Altair 能否在 y 轴上绘制波段,类似于 this Highcharts example?
文档 an example 展示了如何在 y 轴上画一条线,但是将示例改编为使用 plot_rect
来画一个带并不完全奏效:
import altair as alt
from vega_datasets import data
weather = data.seattle_weather.url
chart = alt.Chart(weather).encode(
alt.X("date:T")
)
bars = chart.mark_bar().encode(
y='precipitation:Q'
)
band = chart.mark_rect().encode(
y=alt.value(20),
y2=alt.value(50),
color=alt.value('firebrick')
)
alt.layer(bars, band)
我认为当您使用 alt.value
给出值时的问题是您指定的值是从图表顶部开始的像素值:它没有映射到数据。
在最初的答案中,使用 mark_rule
,它不会创建一个干净的条带,而是创建很多垂直条纹,所以这里有一种正确绘制条带的方法。
第一个解决方案是为波段创建一个全新的数据框,并将其叠加在条形图的顶部:
import altair as alt
import pandas as pd
from vega_datasets import data
weather = data('seattle_weather')
band_df = pd.DataFrame([{'x_min': weather.date.min(),
'x_max': weather.date.max(),
'y_min': 20,
'y_max': 50}])
bars = alt.Chart(weather).mark_bar().encode(
x=alt.X('date:T'),
y=alt.Y('precipitation:Q', title="Precipitation")
)
band_2 = alt.Chart(band_df).mark_rect(color='firebrick', opacity=0.3).encode(
x='x_min:T',
x2='x_max:T',
y='y_min:Q',
y2='y_max:Q'
)
alt.layer(bars, band_2)
第二个选项,如果您不want/cannot创建数据框,则使用transform_calculate
,并在波段图中手动指定x
和x2
:
bars = alt.Chart().mark_bar().encode(
x=alt.X('date:T', title='Date'),
y=alt.Y('precipitation:Q', title="Precipitation")
)
band_3 = alt.Chart().mark_rect(color='firebrick', opacity=0.3).encode(
x='min(date):T',
x2='max(date):T',
y='y_min:Q',
y2='y_max:Q'
).transform_calculate(y_min='20', y_max='50')
alt.layer(bars, band_3, data=data.seattle_weather.url)
初步回答
我会做两件事来模仿您给出的高图示例。首先,使用 transform_calculate
设置 y_min
和 y_max
值。其次,我将使用 mark_rule
以便在 X 轴上有值的区域跨度。 (我还添加了一些不透明度并更改了图层的顺序,以便乐队位于栏杆后面。)
import altair as alt
from vega_datasets import data
weather = data.seattle_weather.url
chart = alt.Chart().encode(
alt.X("date:T")
)
bars = chart.mark_bar().encode(
y='precipitation:Q'
)
band = chart.mark_rule(color='firebrick',
opacity=0.3).encode(
y=alt.Y('y_min:Q'),
y2=alt.Y('y_max:Q')
).transform_calculate(y_min="20",
y_max="50")
alt.layer(band, bars, data=weather)