1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
"""
Mosaic Chart with Labels
------------------------
"""
# category: tables
import altair as alt
from vega_datasets import data
source = data.cars()
base = (
alt.Chart(source)
.transform_aggregate(count_="count()", groupby=["Origin", "Cylinders"])
.transform_stack(
stack="count_",
as_=["stack_count_Origin1", "stack_count_Origin2"],
offset="normalize",
sort=[alt.SortField("Origin", "ascending")],
groupby=[],
)
.transform_window(
x="min(stack_count_Origin1)",
x2="max(stack_count_Origin2)",
rank_Cylinders="dense_rank()",
distinct_Cylinders="distinct(Cylinders)",
groupby=["Origin"],
frame=[None, None],
sort=[alt.SortField("Cylinders", "ascending")],
)
.transform_window(
rank_Origin="dense_rank()",
frame=[None, None],
sort=[alt.SortField("Origin", "ascending")],
)
.transform_stack(
stack="count_",
groupby=["Origin"],
as_=["y", "y2"],
offset="normalize",
sort=[alt.SortField("Cylinders", "ascending")],
)
.transform_calculate(
ny="datum.y + (datum.rank_Cylinders - 1) * datum.distinct_Cylinders * 0.01 / 3",
ny2="datum.y2 + (datum.rank_Cylinders - 1) * datum.distinct_Cylinders * 0.01 / 3",
nx="datum.x + (datum.rank_Origin - 1) * 0.01",
nx2="datum.x2 + (datum.rank_Origin - 1) * 0.01",
xc="(datum.nx+datum.nx2)/2",
yc="(datum.ny+datum.ny2)/2",
)
)
rect = base.mark_rect().encode(
x=alt.X("nx:Q", axis=None),
x2="nx2",
y="ny:Q",
y2="ny2",
color=alt.Color("Origin:N", legend=None),
opacity=alt.Opacity("Cylinders:Q", legend=None),
tooltip=["Origin:N", "Cylinders:Q"],
)
text = base.mark_text(baseline="middle").encode(
x=alt.X("xc:Q", axis=None), y=alt.Y("yc:Q", title="Cylinders"), text="Cylinders:N"
)
mosaic = rect + text
origin_labels = base.mark_text(baseline="middle", align="center").encode(
x=alt.X(
"min(xc):Q",
axis=alt.Axis(title="Origin", orient="top"),
),
color=alt.Color("Origin", legend=None),
text="Origin",
)
(
(origin_labels & mosaic)
.resolve_scale(x="shared")
.configure_view(stroke="")
.configure_concat(spacing=10)
.configure_axis(domain=False, ticks=False, labels=False, grid=False)
)
|