utils/salary_visualization.py

e8577d98faff1bed72ba6f2d204b8b44c6827c23
cleberg.net/utils/salary_visualization.py history · blame · raw

90 lines · 2164 bytes

 1"""
 2A file that will visualize salary data from an incoming CSV.
 3
 4This script reads a CSV file containing salary data and visualizes it using
 5plotly.
 6"""
 7
 8import locale
 9from pandas import read_csv as pd_read_csv
10import pandas as pd
11import plotly.graph_objs as go
12
13locale.setlocale(locale.LC_ALL, "en_US.UTF-8")
14
15# Read the CSV file
16df = pd_read_csv("~/git/cleberg.net/theme/static/salary.csv")
17
18
19def format_currency(value: float) -> str:
20    """
21    Format values in USD currency format.
22
23    Args:
24        value (float): The value to be formatted.
25
26    Returns:
27        str: The formatted value.
28    """
29    return f"${value:,.2f}"
30
31
32# Reverse the order of the DataFrame
33df = df.iloc[::-1].reset_index(drop=True)
34
35# Calculate the percentage increase
36df["Percentage Increase"] = df["Salary"].pct_change() * 100
37
38
39def create_trace(row: pd.Series) -> go.Scatter:
40    """
41    Create a scatter plot trace for a single row.
42
43    Args:
44        row (pd.Series): The row to be plotted.
45
46    Returns:
47        go.Scatter: The created scatter plot trace.
48    """
49    title_company = f"{row['Title']} ({row['Company']})"
50    salary_formatted = format_currency(row["Salary"])
51    if pd.notna(row["Percentage Increase"]):
52        text = f"{salary_formatted} ({row['Percentage Increase']:.2f}%)"
53    else:
54        text = salary_formatted
55    return go.Scatter(
56        x=[row["Start"], row["End"]],
57        y=[row["Salary"], row["Salary"]],
58        text=[text],
59        mode="lines+text",
60        name=title_company,
61        textposition="top center",
62    )
63
64
65# Initialize the plot
66fig = go.Figure()
67
68# Add each data point as a separate trace to display the text
69for index, df_row in df.iterrows():
70    fig.add_trace(create_trace(df_row))
71
72# Update visual styles of the figure
73fig.update_layout(
74    title="Salary Data Over Time (annualized)",
75    xaxis_title="Time",
76    yaxis_title="Salary",
77    font={"family": "monospace", "size": 16},
78    margin={"l": 50, "r": 50, "t": 50, "b": 100},
79    legend={
80        "orientation": "h",
81        "yanchor": "top",
82        "y": -0.3,
83        "xanchor": "center",
84        "x": 0.5,
85    },
86    height=800,
87)
88
89# Display the plot
90fig.show()