Chris Parmer — home

Kobe plot: North Atlantic swordfish stock status 1970-2020

Fisheries

Example from the compendium of canonical charts

Fisheries — Kobe plot: North Atlantic swordfish stock status 1970-2020

Python Code

"""Fisheries — Kobe plot: North Atlantic swordfish stock status 1970-2020."""


import numpy as np
import plotly.graph_objects as go


def generate():
    years = np.arange(1970, 2021)
    n = len(years)

    def make_trajectory(yr, vals):
        return np.interp(years, yr, vals)

    B_Bmsy = make_trajectory(
        [1970, 1980, 1990, 2000, 2005, 2012, 2020],
        [1.20, 0.95, 0.72, 0.60, 0.65, 0.85, 1.10],
    )
    U_Umsy = make_trajectory(
        [1970, 1980, 1990, 1995, 2000, 2005, 2012, 2020],
        [0.80, 1.05, 1.35, 1.60, 1.45, 1.20, 1.00, 0.88],
    )

    RNG = np.random.default_rng(17)
    B_Bmsy += RNG.normal(0, 0.03, n)
    U_Umsy += RNG.normal(0, 0.04, n)

    fig = go.Figure()

    fig.add_shape(type="rect", x0=1, x1=2.5, y0=0, y1=1,
                  fillcolor="rgba(85,182,133,0.20)", line_width=0, layer="below")
    fig.add_shape(type="rect", x0=0, x1=1, y0=1, y1=2.5,
                  fillcolor="rgba(220,50,50,0.18)", line_width=0, layer="below")
    fig.add_shape(type="rect", x0=1, x1=2.5, y0=1, y1=2.5,
                  fillcolor="rgba(233,162,59,0.18)", line_width=0, layer="below")
    fig.add_shape(type="rect", x0=0, x1=1, y0=0, y1=1,
                  fillcolor="rgba(233,162,59,0.13)", line_width=0, layer="below")

    fig.add_vline(x=1, line_dash="dash", line_color=MUTED, line_width=1.5)
    fig.add_hline(y=1, line_dash="dash", line_color=MUTED, line_width=1.5)

    label_kw = dict(showarrow=False, font=dict(size=12, color=MUTED))
    fig.add_annotation(x=1.8, y=0.5, text="Sustainable", **label_kw)
    fig.add_annotation(x=0.35, y=1.6, text="Overfished &<br>Overfishing", **label_kw)
    fig.add_annotation(x=1.8, y=1.7, text="Overfishing", **label_kw)
    fig.add_annotation(x=0.35, y=0.35, text="Recovering", **label_kw)

    fig.add_trace(go.Scatter(
        x=B_Bmsy,
        y=U_Umsy,
        mode="lines",
        line=dict(color=MUTED, width=1.5, dash="dot"),
        showlegend=False,
        hoverinfo="skip",
    ))

    fig.add_trace(go.Scatter(
        x=B_Bmsy,
        y=U_Umsy,
        mode="markers",
        marker=dict(
            size=9,
            color=years,
            colorscale="Plasma",
            line=dict(color="white", width=0.8),
            showscale=False,
        ),
        customdata=years,
        hovertemplate="Year: %{customdata}<br>B/Bmsy: %{x:.2f}<br>U/Umsy: %{y:.2f}<extra></extra>",
        showlegend=False,
    ))

    fig.add_trace(go.Scatter(
        x=[B_Bmsy[0], B_Bmsy[-1]],
        y=[U_Umsy[0], U_Umsy[-1]],
        mode="markers+text",
        marker=dict(size=14, color=["#1f77b4", "#d62728"], symbol=["circle", "star"],
                    line=dict(color="white", width=1)),
        text=["1970", "2020"],
        textposition=["top right", "top right"],
        showlegend=False,
        hoverinfo="skip",
    ))

    fig.update_layout(
        xaxis=dict(title="B / B<sub>MSY</sub>", range=[0.1, 2.2], zeroline=False),
        yaxis=dict(title="U / U<sub>MSY</sub>", range=[0.1, 2.0], zeroline=False),
        showlegend=False,
        margin=dict(t=20, b=60, l=70, r=20),
    )

    return fig


if __name__ == "__main__":
    generate()

Made with Plotly