在 Altair (Python) 中,有没有办法省略条形图的中间值?
In Altair (Python), is there a way to omit the middle values of a bar chart?
我有一个条形图,它显示了一堆值,从高到低排列。但是我有太多(〜100)。我想制作一个省略中间排名值的条形图,以显示具有最高值的条形图和具有最低值的条形图,与 Pandas' DataFrame 的默认显示不同,后者显示前 20 个左右的值,然后是 ...
,然后是最后 20 个左右。所以基本上是一个看起来像这样的图表:
X
XXX
XXXXX
XXXXX ... X
我总是可以创建一个只省略这些值的 DataFrame,但最好能直观地表示这些省略。那可能吗?
我不知道在 Altair 中有什么直接的方法可以做到这一点,但是您可以破解您的 DataFrame 以提供一些不连续性的视觉指示,如下所示:
import pandas as pd
import altair as alt
from vega_datasets import data
raw = data.airports()
df = (raw[raw.country == "USA"]
.groupby("state")
.iata.count()
.rename("number_of_airports")
.sort_values(ascending=False).reset_index()
)
top_bottom = pd.concat(
(df.head(5), pd.DataFrame(data=[["...", 0]], columns=df.columns), df.tail(5)),
ignore_index=True
)
alt.Chart(
top_bottom.reset_index()
).mark_bar().encode(
alt.X("state",
sort=alt.EncodingSortField(field="index", op="sum"),
axis=alt.Axis(labelAngle=0)
),
y="number_of_airports"
)
输出:
Altair 语法对这种图表没有清晰的抽象,但您可以通过一些修改来实现。这是使用 Altair 转换的 @foglerit 答案中显示的相同图表:
import pandas as pd
import altair as alt
from vega_datasets import data
raw = data.airports()
df = (raw[raw.country == "USA"]
.groupby("state")
.iata.count()
.rename("number_of_airports")
.sort_values(ascending=False).reset_index()
)
alt.Chart(df).transform_window(
rank='rank()',
sort=[alt.SortField('number_of_airports', order='descending')]
).transform_filter(
(alt.datum.rank <= 5) | (alt.datum.rank >= 50)
).transform_calculate(
state="datum.rank == 50 ? '...' : datum.state",
number_of_airports="datum.rank == 50 ? 0 : datum.number_of_airports"
).mark_bar().encode(
alt.X("state:N",
sort=alt.EncodingSortField(field="rank"),
axis=alt.Axis(labelAngle=0)
),
y="number_of_airports:Q"
)
我有一个条形图,它显示了一堆值,从高到低排列。但是我有太多(〜100)。我想制作一个省略中间排名值的条形图,以显示具有最高值的条形图和具有最低值的条形图,与 Pandas' DataFrame 的默认显示不同,后者显示前 20 个左右的值,然后是 ...
,然后是最后 20 个左右。所以基本上是一个看起来像这样的图表:
X
XXX
XXXXX
XXXXX ... X
我总是可以创建一个只省略这些值的 DataFrame,但最好能直观地表示这些省略。那可能吗?
我不知道在 Altair 中有什么直接的方法可以做到这一点,但是您可以破解您的 DataFrame 以提供一些不连续性的视觉指示,如下所示:
import pandas as pd
import altair as alt
from vega_datasets import data
raw = data.airports()
df = (raw[raw.country == "USA"]
.groupby("state")
.iata.count()
.rename("number_of_airports")
.sort_values(ascending=False).reset_index()
)
top_bottom = pd.concat(
(df.head(5), pd.DataFrame(data=[["...", 0]], columns=df.columns), df.tail(5)),
ignore_index=True
)
alt.Chart(
top_bottom.reset_index()
).mark_bar().encode(
alt.X("state",
sort=alt.EncodingSortField(field="index", op="sum"),
axis=alt.Axis(labelAngle=0)
),
y="number_of_airports"
)
输出:
Altair 语法对这种图表没有清晰的抽象,但您可以通过一些修改来实现。这是使用 Altair 转换的 @foglerit 答案中显示的相同图表:
import pandas as pd
import altair as alt
from vega_datasets import data
raw = data.airports()
df = (raw[raw.country == "USA"]
.groupby("state")
.iata.count()
.rename("number_of_airports")
.sort_values(ascending=False).reset_index()
)
alt.Chart(df).transform_window(
rank='rank()',
sort=[alt.SortField('number_of_airports', order='descending')]
).transform_filter(
(alt.datum.rank <= 5) | (alt.datum.rank >= 50)
).transform_calculate(
state="datum.rank == 50 ? '...' : datum.state",
number_of_airports="datum.rank == 50 ? 0 : datum.number_of_airports"
).mark_bar().encode(
alt.X("state:N",
sort=alt.EncodingSortField(field="rank"),
axis=alt.Axis(labelAngle=0)
),
y="number_of_airports:Q"
)