Skip to content

Add an example to the "Maps" section that shows trajectories of hurricanes #735

@thomascamminady

Description

@thomascamminady

I wonder whether it would help to add another example to the "Maps" section in the examples that illustrates who geo data, especially trajectories, can be visualized.
I think the only other example that illustrates this is the London Tube Lines example and I actually missed this at first because it was in the "Case Studies" section.

Here's a version of what I hope is a useful (interactive) example that might be added as an example.

hurricanes

And here's the source code.

Code block

legend_selection = alt.selection_point(fields=["Year"], bind="legend")


storms = (
    alt.Chart(df)
    .mark_trail()
    .encode(
        longitude=alt.Longitude("Longitude:Q"),
        latitude=alt.Latitude("Latitude:Q"),
        color=alt.Color("Year:N"),
        detail=alt.Detail("ID:N"),
        size=alt.Size("Maximum Wind:Q").scale(range=(0, 5)),
        opacity=alt.condition(legend_selection, alt.value(1.0), alt.value(0.1)),
    )
    .add_params(legend_selection) # of course we could also skip interactivity
)

map_background = alt.Chart(
    alt.topo_feature(data.world_110m.url, feature="countries")
).mark_geoshape(stroke="white", strokeWidth=2, color="lightgray")


chart = (
    alt.layer(map_background, storms)
    .project(translate=[1000, 600], scale=500)
    .properties(width=700, height=700)
)


chart

Now there's one caveat: The data that I use is taken from Kaggle, although the original data comes from the National Hurricane Center and is published under the CC0 license. I downloaded the data from Kaggle and performed some post-processing, the steps are shown below.

Code block

# data from https://www.kaggle.com/datasets/noaa/hurricane-database

df = (
    pl.read_csv("./atlantic.csv")
    .with_columns(
        pl.col("Date")
        .cast(str)
        .apply(lambda s: s[:4] + "-" + s[4:6] + "-" + s[6:])
        .str.strptime(pl.Date, fmt="%Y-%m-%d"),
        pl.col("Latitude").apply(
            lambda s: float(str(s[:-1])) if s[-1] == "N" else -float(str(s[:-1]))
        ),
        pl.col("Longitude").apply(
            lambda s: -float(str(s[:-1])) if s[-1] == "W" else float(str(s[:-1]))
        ),
    )
    .with_columns(
        pl.struct(["Date", "Time"])
        .apply(lambda s: f"""{s["Date"]}-{s["Time"]//100:02d}""")
        .str.strptime(pl.Datetime, fmt="%Y-%m-%d-%H")
        .alias("Datetime")
    )
    .with_columns(pl.col("Maximum Wind").cast(float))
    .with_columns(pl.col("Date").dt.year().alias("Year"))
    .with_columns(
        (pl.col("Datetime") - pl.col("Datetime").first())
        .over("ID")
        .dt.hours()
        .alias("Age")
    )
    .sort("ID", "Datetime")
    .filter(pl.col("Date").dt.year() > 2010)
    .to_pandas()
)

If there's some interest in this example, maybe adding this data to the vega_datasets repository might be an option?
I am happy to pursue this further if the route via vega_datasets would make sense.

Regardless of whether or not this example will be added, I do think an example that shows how to plot routes (initially, I wanted to plot my running routes) would help.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions