Как построить полосы оси Y на диаграммах Альтаира?

Может ли Альтаир нанести полосы на ось y, как в этом примере Highcharts?

В документах есть пример, показывающий, как нарисовать линию по оси 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)

plot_rect с фиксированными y и y2


person ejain    schedule 31.10.2018    source источник


Ответы (1)


Я думаю, что проблема, когда вы задаете значение с помощью 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)

введите здесь описание изображения

Второй вариант, если вы не хотите / не можете создать фрейм данных, - использовать 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)

введите здесь описание изображения

Первоначальный ответ

Я бы сделал 2 вещи, чтобы имитировать приведенный вами пример highchart. Сначала используйте 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_plot_with_band

person FlorianGD    schedule 08.11.2018
comment
Если вы увеличите масштаб, красная область состоит из множества вертикальных линий (по одной на значение x в данных), так что это не сработает, если бы в данных были пробелы ... mark_rect, с другой стороны, работает, но отображается наложиться один раз для каждого значения, так что в конечном итоге он будет твердым даже при низком значении непрозрачности ... - person ejain; 12.11.2018