Landing sequence

One chart per runway.
One line per landing attempt, starting when the aircraft aligns with the ILS.
The color matches the number of go arounds.

See how the configuration changed after two aircraft failed their landing.

callsign ILS final approach landing go around
AFL2390 14 2019-10-15 10:11:17+00:00 2019-10-15 10:14:07+00:00 0
SWR53E 14 2019-10-15 10:13:10+00:00 2019-10-15 10:15:46+00:00 0
SWR287A 14 2019-10-15 10:14:46+00:00 2019-10-15 10:17:40+00:00 2
HBVTB 14 2019-10-15 10:21:21+00:00 2019-10-15 10:24:01+00:00 0
BAW712T 14 2019-10-15 10:22:51+00:00 2019-10-15 10:26:06+00:00 0
SWR135G 14 2019-10-15 10:24:14+00:00 2019-10-15 10:27:31+00:00 0
EDW27 14 2019-10-15 10:25:56+00:00 2019-10-15 10:29:06+00:00 0
SWR287A 14 2019-10-15 10:28:41+00:00 2019-10-15 10:31:23+00:00 2
SWR46J 14 2019-10-15 10:30:06+00:00 2019-10-15 10:33:21+00:00 1
NJE715R 14 2019-10-15 10:31:58+00:00 2019-10-15 10:35:04+00:00 0
GSW4943 14 2019-10-15 10:34:04+00:00 2019-10-15 10:36:47+00:00 0
SWR287A 28 2019-10-15 10:41:58+00:00 2019-10-15 10:45:31+00:00 2
SWR46J 28 2019-10-15 10:43:29+00:00 2019-10-15 10:48:12+00:00 1
TYW212F 28 2019-10-15 10:47:02+00:00 2019-10-15 10:49:59+00:00 0
from traffic.data.datasets import landing_zurich_2019
import altair as alt

data = (
    landing_zurich_2019.between("2019-10-15 10:10", "2019-10-15 10:50")
    .all("aligned_on_LSZH")
    .assign(go=lambda df: df.index_.max())
    .drop(columns=["flight_id"])
    .summary(["callsign", "ILS_max", "start", "stop", 'go_max'])
    .eval(desc="")
    .sort_values("stop")
    .rename(columns=
        dict(
            ILS_max="ILS",
            start="final approach",
            stop="landing",
            go_max="go around"
        )
    )
)

chart = alt.Chart(data)

(
    (
        c.mark_rule(size=3).encode(
            alt.X("utchoursminutes(final approach)", axis=alt.Axis(title="",),),
            alt.X2("utchoursminutes(landing)"),
            alt.Y("landing:N", sort="descending", axis=None),
            alt.Color("go around:N"),
        )
        + c.mark_text(baseline="middle", align="left", dx=12).encode(
            alt.X("utchoursminutes(landing)"),
            alt.Y("landing:N"),
            alt.Text("callsign"),
            alt.Color("go around:N"),
        )
        + c.mark_text(baseline="middle", align="left", size=20, dy=1, dx=-8).encode(
            alt.X("utchoursminutes(landing)"),
            alt.Y("landing:N"),
            alt.Color("go around:N"),
            text=alt.value("✈"),
        )
    )
    .properties(width=500, height=150)
    .facet(row="ILS")
    .configure_axis(labelFontSize=14,)
    .configure_header(
        labelFontSize=24,
        labelFont="Ubuntu",
        labelOrient="right",
        labelPadding=-30,
        title=None,
    )
    .configure_legend(orient="top")
    .configure_text(font="Ubuntu")
)