проблема с сортировкой гистограммы в altair, наложенной на слои с текстом отметки - PullRequest
1 голос
/ 26 мая 2020
chart_df= alt.Chart(df).mark_bar().encode(
    x = 'value',
    y = alt.Y('name', sort='-x'),
    color = 'variable'
)

для добавления значения каждого столбца в виде текста, я использую следующий код, но я потерял отсортированные столбцы.

chart_df_text = chart_df.mark_text().encode(
    x = 'text_margin_from_bar:Q',
    text = 'human_readable_value:Q',
).transform_calculate(
    human_readable_value = expr.toString(expr.floor(datum.value/10**7)),
    text_margin_from_bar = datum.value + (datum.value/expr.abs(datum.value))*1000000000
    # i have negetive and positive numbers, so for have a space between number and bar, i do this
)

добавить

y = alt.Y('name', sort='-x'),

в chart_df_text, но все еще у меня проблема. Я прочитал еще один вопрос, в котором есть моя проблема, в котором говорится, что проблема связана с версией altair, но я нахожусь в последней версии.

1 Ответ

2 голосов
/ 27 мая 2020

Предупреждение в консоли javascript сообщает вам, почему это не работает:

[Warning] Dropping sort property {"field":"value","op":"sum"} as unioned domains only support boolean or op "count", "min", and "max".
[Warning] Domains that should be unioned has conflicting sort properties. Sort will be set to true.

Вы можете обойти это, используя поддерживаемый op в вашей сортировке. Например:

import pandas as pd
import altair as alt
from altair import expr, datum

df = pd.DataFrame({
    'value': [-3E9, -4E9, 6E9, 1E10, -8E9],
    'name': ['Bob', 'Sue', 'Tim', 'Ann', 'Bill'],
    'variable': range(5)
})

chart_df= alt.Chart(df).mark_bar().encode(
    x = 'value',
    y = alt.Y('name', sort=alt.EncodingSortField('value', op='min', order='descending')),
    color = 'variable'
)

chart_df_text = chart_df.mark_text().encode(
    x = 'text_margin_from_bar:Q',
    text = 'human_readable_value:Q',
).transform_calculate(
    human_readable_value = expr.toString(expr.floor(datum.value/10**7)),
    text_margin_from_bar = datum.value + (datum.value/expr.abs(datum.value))*1000000000
)

chart_df + chart_df_text

enter image description here

...