пытался изобразить несколько слоев диаграммы , прежде чем я понял, что спецификация слоя не была проблемой, но то, что каким-то образом срез, который я прохожу по диаграмме, действует (для меня) странно.Если он не сломан, то я должен неправильно понять, как все должно работать.
Прилагаю конкретный пример, чтобы продемонстрировать, как это работает и как я думаю, что это не должно работать так.
import altair as alt
alt.renderers.enable('notebook')
import pandas as pd
idx = pd.IndexSlice
history_index = pd.date_range(start="31jan2016", end="30jun2019", freq="M")
forecast_index = pd.date_range(start="31jan2019", end="31dec2019", freq="M")
history_df = pd.DataFrame([z for z in range(len(history_index))], index=history_index,columns = ['history'])
forecast_df = pd.DataFrame([z for z in range(len(forecast_index))], index=forecast_index, columns = ['forecast'])
df = history_df.join(forecast_df, how="outer")
df.index.name = "date"
Первый пример работает:
#without making it a seasonal chart, this works
non_seasonal = alt.Chart(df.loc[idx['20170701':],:].reset_index(), title=f"non seasonal plot").mark_line().encode(
x='date',
y=alt.Y(f'forecast', scale=alt.Scale(zero=False)),
)
non_seasonal
Но когда я начинаю превращать их в сезонные графики, делая месяц оси X, возникают проблемы.
Мой первый срез работает, я просто нарезаю все существующие forecast
данные, которые начинаются в январе2019 года.
#works ok: shows all the data since 1jan2019
seasonal1 = alt.Chart(df.loc[idx['20190101':],:].reset_index(), title=f"seasonal plot").mark_line().encode(
x='month(date)',
y=alt.Y(f'forecast', scale=alt.Scale(zero=False)),
)
seasonal1
Но когда я начинаю нарезку с более ранних дат (до того, как «прогноз» получит какие-либо данные), у меня возникают проблемы.
#fails: shows no data
seasonal2 = alt.Chart(df.loc[idx['20180101':],:].reset_index(), title=f"seasonal plot").mark_line().encode(
x='month(date)',
y=alt.Y(f'forecast', scale=alt.Scale(zero=False)),
)
seasonal2
Я могу отобразить данные, если добавлю цветовую кодировку, но это не то решение, которое в конечном итоге мне пригодится.
#works if I add a color-encoding
seasonal3 = alt.Chart(df.loc[idx['20180101':],:].reset_index(), title=f"seasonal plot").mark_line().encode(
x='month(date)',
y=alt.Y(f'forecast', scale=alt.Scale(zero=False)),
color="year(date):N"
)
seasonal3
В этот момент все становится очень странным.Если я начну свой слайс где-нибудь в 2018 году, то вместо этого «начало» слайса будет действовать как «конец» слайса ....
#fails bizarrely -- the 20180701 slice appears to be the END of the slice, not the start
seasonal4 = alt.Chart(df.loc[idx['20180701':],:].reset_index(), title=f"seasonal plot").mark_line().encode(
x='month(date)',
y=alt.Y(f'forecast', scale=alt.Scale(zero=False)),
)
seasonal4
Опять же, это работает, если я назначу ему цветовую кодировку
#again, it works if I add a color encoding.
seasonal5 = alt.Chart(df.loc[idx['20180701':],:].reset_index(), title=f"seasonal plot").mark_line().encode(
x='month(date)',
y=alt.Y(f'forecast', scale=alt.Scale(zero=False)),
color="year(date):N"
)
seasonal5
Итак, очевидный способ обойти этодобавить цветовую кодировку.Но это не сработает для меня, так как я пытаюсь наложить несколько наборов данных на этом графике (исторические данные окрашены по годам) и прогнозные данные жестко закодированы в красный цвет.
==================================================
Основываясь на ответе Джейка ниже, я достигаю желаемого конечного продукта:
forecast = alt.Chart(df.loc[idx['20180101':],'forecast'].reset_index().dropna(), title=f"seasonal plot").mark_line(color="green").encode(
x='month(date)',
y=alt.Y(f'forecast', scale=alt.Scale(zero=False)),
)
history = alt.Chart(df.loc[idx['20170101':],'history'].reset_index().dropna(), title=f"seasonal plot").mark_line().encode(
x='month(date)',
y=alt.Y(f'history', scale=alt.Scale(zero=False)),
color="year(date):O"
)
forecast+history