首页 > 解决方案 > Altair 图表 - 自定义轴格式化程序功能

问题描述

我可以在 Matplotlib 中使用以下表达式:

def format_func(value, tick_number):
    d = datetime.date(1998,1,1) + datetime.timedelta(value)
    return d.strftime("%B")

ax.xaxis.set_major_formatter(plt.FuncFormatter(format_func))

当 X 轴值包含一年中的某一天 (1-365) 时,将其转换为相应月份的名称。

在此处输入图像描述

我可以在 Altair 中达到同样的效果吗?

在此处输入图像描述

编辑:

感谢@joelostblom。添加一段代码来指定我正在使用的确切数据框。下面代码的当前问题是,在我的示例中,我有

# pre-existing dataframe
num_days = 365 * 4 # four days
df = pd.DataFrame(
    {
    'Timestamp': [
        (datetime.datetime.now() - datetime.timedelta(num_days) ) + datetime.timedelta(days=x) 
        for x in range(num_days)
    ],
    'value': pd.Series(np.random.randn(num_days))
    }
)
df = df.set_index('Timestamp')

# extra columns that may be needed by altair
df['Month'] = df.index.month_name()
df['Year'] = df.index.year

到目前为止,我已经尝试以两种方式使用 Altair:

alt.Chart(df.reset_index()).mark_line().encode(
    x='Month',
    y='value',
    color=alt.Color('Year:O', scale=alt.Scale(scheme='category10')),
)

在此处输入图像描述

或者像你建议的那样:

alt.Chart(df.reset_index()).mark_line().encode(
    x=alt.X('Timestamp', axis=alt.Axis(format='%b')),
    y='value',
    color=alt.Color('Year:O', scale=alt.Scale(scheme='category10')),
)

在此处输入图像描述

你能帮我理解我做错了什么吗?

标签: pythonlinechartaltair

解决方案


您可以使用以下方法转换一年中的日期做一个日期戳pandas.to_datetime

import altair as alt
import numpy as np
import pandas as pd


# Setup data
x = np.arange(365)
source = pd.DataFrame({
  'x': x,
  'f(x)': np.sin(x / 50)
})

# Convert to date
source['date'] = pd.to_datetime(source['x'], unit='D', origin='2020')

alt.Chart(source).mark_line().encode(
    x='date',
    y='f(x)'
)

在此处输入图像描述

如果您想要轴上的所有月份名称,您可以更改轴格式:

alt.Chart(source).mark_line().encode(
    x=alt.X('date', axis=alt.Axis(format='%b')),
    y='f(x)'
)

在此处输入图像描述

对于有多年的更新示例,您可以使用Altair/Vega-Lite 中的时间单位聚合。例如, using'monthdate(Timestamp)'将忽略年份并按月份和日期聚合(请注意,并非 Vega-Lite 文档中的所有聚合都在 Altair 中可用)。

import pandas as pd
import altair as alt 
import datetime
import numpy as np


# pre-existing dataframe
num_days = 365 * 4 # four years
df = pd.DataFrame(
    {
    'Timestamp': [
        (datetime.datetime.now() - datetime.timedelta(num_days) ) + datetime.timedelta(days=x) 
        for x in range(num_days)
    ],
    'value': pd.Series(np.random.randn(num_days))
    }
)

alt.Chart(df).mark_line().encode(
    x=alt.X('monthdate(Timestamp)', axis=alt.Axis(format='%b')),
    y='value',
    color=alt.Color('year(Timestamp):O', scale=alt.Scale(scheme='category10')),
)

在此处输入图像描述


推荐阅读