Сортировка гистограммы с накоплением - PullRequest
1 голос
/ 05 октября 2019

Я могу создать гистограмму с накоплением, выполнив следующие действия:

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

data = {'First': {('Header-1', 'H1-A'): 'Red',
                  ('Header-1', 'H1-B'): 'Red',
                  ('Header-1', 'H1-C'): 'Red',
                  ('Header-2', 'H2-A'): 'White',
                  ('Header-2', 'H2-B'): 'White',
                  ('Header-2', 'H2-C'): 'Yellow',
                  ('Header-3', 'H3-A'): 'Red',
                  ('Header-3', 'H3-B'): 'White',
                  ('Header-3', 'H3-C'): 'White',
                  ('Header-3', 'H3-D'): 'Yellow'},
        'Second': {('Header-1', 'H1-A'): 'White',
                   ('Header-1', 'H1-B'): 'Yellow',
                   ('Header-1', 'H1-C'): 'Yellow',
                   ('Header-2', 'H2-A'): 'Yellow',
                   ('Header-2', 'H2-B'): 'Green',
                   ('Header-2', 'H2-C'): 'Green',
                   ('Header-3', 'H3-A'): 'Green',
                   ('Header-3', 'H3-B'): 'Red',
                   ('Header-3', 'H3-C'): 'Red',
                   ('Header-3', 'H3-D'): 'White'},
        'Third': {('Header-1', 'H1-A'): 'Red',
                  ('Header-1', 'H1-B'): 'Green',
                  ('Header-1', 'H1-C'): 'Green',
                  ('Header-2', 'H2-A'): 'Green',
                  ('Header-2', 'H2-B'): 'White',
                  ('Header-2', 'H2-C'): 'White',
                  ('Header-3', 'H3-A'): 'White',
                  ('Header-3', 'H3-B'): 'Green',
                  ('Header-3', 'H3-C'): 'Green',
                  ('Header-3', 'H3-D'): 'Yellow'},        
       }
df = pd.DataFrame(data)
column_counts = df.apply(pd.Series.value_counts).fillna(0)
column_counts[column_counts.columns] = column_counts[column_counts.columns].astype('int64')
unstacked = pd.DataFrame(column_counts.unstack())
unstacked = unstacked.reset_index()
unstacked.columns = ['category','kind','counts']
alt.Chart( unstacked ).mark_bar().encode(
    x='category',
    y='sum(counts)',
    color='kind'
)

У меня есть некоторый контроль над порядком стеков, выполнив:

alt.Chart( unstacked ).mark_bar().encode(
    x='category',
    y='sum(counts)',
    color='kind',
    order=alt.Order(
      'kind',
      sort='descending'
    )
)

Однако,Параметр сортировки alt.Order принимает только «восходящий» или «нисходящий». Я бы хотел настроить заказ следующим образом: зеленый, желтый, красный, белый.

Возможно ли это? Как?

1 Ответ

1 голос
/ 05 октября 2019

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

Это можно сделать с помощью вычисления преобразования в спецификации диаграммы (версия этого подхода vega-lite для порядка стеков)обозначается здесь ) или путем предварительной обработки данных в Pandas.

Вот пример подхода предварительной обработки:

unstacked['order'] = unstacked['kind'].replace(
    {val: i for i, val in enumerate(['Green', 'Yellow', 'Red', 'White'])}
)

alt.Chart( unstacked ).mark_bar().encode(
    x='category',
    y='sum(counts)',
    color=alt.Color('kind',
        # optional: make color order in legend match stack order
        sort=alt.EncodingSortField('order', order='descending')
    ),
    order='order',  # this controls stack order
)

enter image description here

...