简体   繁体   English

如何在Altair图表中绘制y轴带?

[英]How to plot y-axis bands in Altair charts?

Can Altair plot bands on the y axis, similar to this Highcharts example ? Altair能否在y轴上绘制波段,类似于此Highcharts示例

The docs have an example showing how to draw a line on the y axis, but adapting the example to use plot_rect to draw a band instead doesn't quite work: 该文档有一个示例,显示了如何在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)

具有固定y和y2的plot_rect

I think the problem when you give a value with alt.value is that you specify the value in pixels starting from the top of the graph : it is not mapped to the data. 我认为当您使用alt.value时,问题在于您从图的顶部开始以像素为单位指定该值:它未映射到数据。

In the initial answer, with mark_rule , it would'nt create a clean band but a lot of vertical stripes, so here is a way to correctly plot a band. 在最初的答案中,使用mark_rule不会创建干净的条带,但会产生很多垂直条纹,因此这是一种正确绘制条带的方法。

First solution is to create a brand new data frame for the band, and layer that on top of the bars: 第一个解决方案是为乐队创建一个全新的数据框架,并在条形图的顶部进行分层:

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)

在此处输入图片说明

Second option, if you do not want/cannot create a dataframe, is to use transform_calculate , and manually specify x and x2 in the band chart: 如果您不希望/无法创建数据框,第二个选择是使用transform_calculate ,并在能带图中手动指定xx2

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)

在此处输入图片说明

Initial answer 初步答案

I would do 2 things to mimic the highchart example you gave. 我会做两件事来模仿您给出的高图表示例。 First, use a transform_calculate to set y_min and y_max values. 首先,使用transform_calculate设置y_miny_max值。 And second, I'll use mark_rule so that the band span on the X axis where there are values. 其次,我将使用mark_rule以便使带跨度在X轴上有值的位置。 (I also added some opacity and changed the order of the layers so that the band is behind the bars.) (我还添加了一些不透明度,并更改了图层的顺序,以使色带位于条形后面。)

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_plot_with_band

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM