Mortality curve
Actuarial — qx by age and sex, log y-axis
Example from the compendium of canonical charts
Python Code
"""Actuarial — Mortality curve (qx by age and sex, log y-axis)."""
import pandas as pd
import plotly.graph_objects as go
URL = "https://vincentarelbundock.github.io/Rdatasets/csv/dslabs/death_prob.csv"
def generate():
print("fetching death_prob from Rdatasets …")
df = fetch_csv(URL)
print("columns:", df.columns.tolist())
print(df.head(3))
df.columns = [c.strip().lower() for c in df.columns]
# Expected cols: age, sex, prob
male = df[df["sex"].str.lower() == "male"].sort_values("age")
female = df[df["sex"].str.lower() == "female"].sort_values("age")
fig = go.Figure()
fig.add_trace(go.Scatter(
x=male["age"], y=male["prob"],
mode="lines", name="Male",
line=dict(color=VIOLET, width=2),
hovertemplate="Age %{x}: %{y:.5f}<extra>Male</extra>",
))
fig.add_trace(go.Scatter(
x=female["age"], y=female["prob"],
mode="lines", name="Female",
line=dict(color=GREEN, width=2),
hovertemplate="Age %{x}: %{y:.5f}<extra>Female</extra>",
))
# Annotations — use nearest age to avoid exact-match failure on non-integer ages
def yval(df_sex, age):
idx = (df_sex["age"] - age).abs().idxmin()
return float(df_sex.loc[idx, "prob"])
male_20 = yval(male, 20)
female_10 = yval(female, 10)
male_75 = yval(male, 75)
annotations = [
dict(x=20, y=male_20,
text="Accident hump", showarrow=True, arrowhead=2,
ax=0, ay=-50, font=dict(size=11, color=MUTED),
bgcolor="rgba(255,255,255,0.85)", bordercolor="#cccccc"),
dict(x=10, y=female_10,
text="Childhood trough", showarrow=True, arrowhead=2,
ax=75, ay=-40, font=dict(size=11, color=MUTED),
bgcolor="rgba(255,255,255,0.85)", bordercolor="#cccccc"),
dict(x=75, y=male_75,
text="Senescence rise", showarrow=True, arrowhead=2,
ax=-75, ay=-40, font=dict(size=11, color=MUTED),
bgcolor="rgba(255,255,255,0.85)", bordercolor="#cccccc"),
]
fig.update_layout(
xaxis=dict(title="Age"),
yaxis=dict(title="Annual probability of death (qx)", type="log"),
legend=dict(orientation="h", y=-0.14),
margin=dict(t=50, b=70, l=80, r=40),
annotations=annotations,
)
return fig
if __name__ == "__main__":
generate()
Made with Plotly