在 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"
)