import altair as alt
from vega_datasets import data
# get iris dataset and take 120 observations from it
source = data.iris()[10:130]
# add one more feature to dataset
colors = ['red', 'orange', 'blue', 'red'] * 30
source['colors'] = colors
chart = alt.Chart(source).mark_bar().encode(
alt.Y('species:N', sort='x'),
alt.X('count():Q', stack='zero'),
color=alt.Color('colors', sort=colors),
order="colors",
)
text = alt.Chart(source).mark_text(dx=-7, dy=3, color='white')\
.encode(
alt.Y("species:N", sort='x'),
alt.X('count():Q', stack="zero"),
order="colors",
text=alt.Text('count():Q')
)
chart + text
Now I want to normalize this chart and labels should represent fraction of a whole.
import altair as alt
from vega_datasets import data
source = data.iris()[10:130]
colors = ['red', 'orange', 'blue', 'red'] * 30
source['colors'] = colors
chart = alt.Chart(source).mark_bar().encode(
alt.Y('species:N', sort='x'),
alt.X('count():Q', stack='normalize'),
color=alt.Color('colors', sort=colors),
order="colors",
)
text = alt.Chart(source).mark_text(dx=-7, dy=3, color='white')\
.encode(
alt.Y("species:N", sort='x'),
alt.X('count():Q', stack="normalize"),
order="colors",
text=alt.Text('count():Q')
)
chart + text
So in this example instead of 8, 7, 15 for 1st bar I want to see 0.27, 0.23, 0.5 (rounded to 2 digits after comma). How can I achieve this?
update This is how I managed to progress:
import altair as alt
from vega_datasets import data
source = data.iris()[10:130]
colors = ['red', 'orange', 'blue', 'red'] * 30
sort_order=['blue', 'orange', 'red']
source['colors'] = colors
chart = alt.Chart(source).mark_bar().encode(
alt.Y('species:N', sort='x'),
alt.X('count():Q', stack='normalize'),
color=alt.Color('colors', sort=sort_order),
order = 'colors'
)
text = alt.Chart(source).transform_aggregate(count='count()', groupby=['species', 'colors'])\
.transform_joinaggregate(total='sum(count)', groupby=["species"])\
.transform_calculate(frac=alt.datum.count / alt.datum.total)\
.mark_text(align='right', dx=-7, dy=3, color='white')\
.encode(
alt.Y("species:N", sort='x'),
alt.X('count():Q', stack="normalize"),
text=alt.Text('frac:Q', format='.0%'),
order = 'colors'
)
chart + text
But labels are not aligned correctly (I need them to be just at the end of each color, just how in first two pictures). Any ideas how to fix it?
from How to put fraction labels in normalized bar chart in Altair?
No comments:
Post a Comment