我的数据如下所示:
姓名 | 日期 | 1% | 2% | 10% | ... | 100% |
---|---|---|---|---|---|---|
安妮 | 1/1/24 | 3 | 5 | 1 | ... | 92 |
安妮 | 1/2/24 | 4 | 8 | 2 | ... | 78 |
安妮 | 1/3/24 | 7 | 9 | 6 | ... | 47 |
我的 x 轴是百分比:1%、2%、5%、10%、15%、25%、50% 和 100%
我使用 Altair 创建了我的表格:
import altair as alt
chart_df = newdf.drop(columns = ['NAME'])
chart_df = chart_df.astype({col: 'float' for col in chart_df.columns if col != 'DATE'})
numeric_cols = sorted(chart_df.columns[1:].to_list(), key=float)
chart_df = chart_df[['DATE'] + numeric_cols]
chart_df['DATE'] = pd.to_datetime(chart_df['DATE'], format='%Y.%m.%d')
chart_df = chart_df.melt(id_vars = ['DATE'], var_name = '%age', value_name = 'Output')
chart_df['DATE'] = chart_df['DATE'].dt.strftime('%Y-%m-%d')
#st.write('Melted Dataframe:', chart_df)
chart = alt.Chart(chart_df).mark_circle(size = 60).encode(alt.X('%age:O',
sort = numeric_cols),
alt.Y('Output:Q'),
color='DATE:N',
tooltip=['DATE:N', '%age:O', 'Output:Q']
).properties(width = 600, height = 400)
st.altair_chart(chart, use_container_width = True)
这看起来不错,但 x 轴值以固定距离分隔,而不是在 0-100 范围之间分隔的实际值。 1% 和 2% 处的值应该比 2% 和 5% 处的值更近,但它们的距离都相同。
出现您遇到的问题是因为 Altair 将百分比(1%、2%、5%、10% 等)视为序数值(编码中的 O 类型),这导致它们沿着x 轴,而不是遵循 0 到 100 范围内的值的实际分布。
要解决此问题并确保 x 轴反映百分比的真实数字间距,您应该将 x 轴视为定量刻度 (Q),并确保百分比值表示为实际数字(即, 1%、2%、5%、10% 等应为 1、2、5、10...)。
调整步骤:
将百分比值转换为数字格式:您需要将“%age”列从“1%”、“2%”等字符串更改为 1、2、5 等数值,因此Altair 可以适当缩放它们。
使用定量刻度:x 轴应被视为定量刻度 (Q),以便 Altair 根据实际数值自动调整点之间的间距。
刻度调整:确保 x 轴覆盖从 0% 到 100% 的整个范围,无论数据范围如何。如果您想放大到特定范围,可以调整此值。
代码修复(以及带有玩具数据集的演示):
import pandas as pd
import altair as alt
import numpy as np
# Create a toy DataFrame with Date and percentage columns
data = {
'Name': ['Anne', 'Anne', 'Anne', 'Bob', 'Bob', 'Bob'],
'Date': ['1/1/24', '1/2/24', '1/3/24', '1/1/24', '1/2/24', '1/3/24'],
'1%': [3, 4, 7, 2, 5, 6],
'2%': [5, 8, 9, 3, 6, 7],
'5%': [12, 14, 15, 11, 13, 16],
'10%': [20, 23, 25, 18, 22, 24],
'15%': [25, 28, 30, 22, 27, 29],
'25%': [30, 35, 40, 32, 36, 38],
'50%': [45, 50, 55, 48, 52, 57],
'100%': [92, 78, 47, 89, 80, 59]
}
# Convert the data into a DataFrame
df = pd.DataFrame(data)
# Melt the DataFrame to long format
df_melted = df.melt(id_vars=['Name', 'Date'], var_name='%age', value_name='Output')
# Convert the %age column to numeric values (strip '%' and convert to float)
df_melted['%age'] = df_melted['%age'].str.rstrip('%').astype(float)
# Create the Altair chart
chart = alt.Chart(df_melted).mark_circle(size=60).encode(
alt.X('%age:Q', title='Percentage', scale=alt.Scale(domain=[0, 100])), # Use Q scale for x-axis
alt.Y('Output:Q', title='Output'),
color='Date:N',
tooltip=['Date:N', '%age:Q', 'Output:Q']
).properties(
width=600,
height=400
)
# Display the chart
chart