Skip to content

Commit

Permalink
Violinplot and boxplot logic working
Browse files Browse the repository at this point in the history
  • Loading branch information
Casper-Guo committed Aug 20, 2024
1 parent f8f0844 commit 6a6f217
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 12 deletions.
4 changes: 3 additions & 1 deletion app.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,9 @@ def render_compound_plot(
return go.Figure()

included_laps = pd.DataFrame.from_dict(included_laps)
included_laps = included_laps[included_laps["Compound"].isin(compounds)]
included_laps = included_laps[
(included_laps["Compound"].isin(compounds)) & (included_laps["PctFromLapRep"] <= 10)
]

y = "DeltaToLapRep" if show_seconds else "PctFromLapRep"
fig = go.Figure()
Expand Down
58 changes: 53 additions & 5 deletions f1_visualization/plotly_dash/graphs.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,14 +294,15 @@ def compounds_lineplot(included_laps: pd.DataFrame, y: str, compounds: list[str]
fig = go.Figure()
yaxis_title = "Seconds to LRT" if y == "DeltaToLapRep" else "Percent from LRT"

# TODO: remove this hard-coded value
_, palette, marker, _ = _plot_args(2024)
_, palette, marker, _ = _plot_args()
max_stint_length = 0

for compound in compounds:
compound_laps = included_laps[included_laps["Compound"] == compound]
# clip tyre life range to where there are at least three records
tyre_life_range = compound_laps.groupby("TyreLife").size()
tyre_life_range = tyre_life_range[tyre_life_range >= 3].index
max_stint_length = max(max_stint_length, tyre_life_range.max())
median_LRT = compound_laps.groupby("TyreLife")[y].median(numeric_only=True) # noqa: N806
median_LRT = median_LRT.loc[tyre_life_range] # noqa: N806

Expand All @@ -311,7 +312,6 @@ def compounds_lineplot(included_laps: pd.DataFrame, y: str, compounds: list[str]
y=median_LRT,
line={"color": palette[compound]},
marker={
# TODO: tune these parameters
"line": {"width": 1, "color": "white"},
"color": palette[compound],
"symbol": marker[compound],
Expand All @@ -324,7 +324,11 @@ def compounds_lineplot(included_laps: pd.DataFrame, y: str, compounds: list[str]

fig.update_layout(
template="plotly_dark",
xaxis_title="Tyre Age",
xaxis={
"tickmode": "array",
"tickvals": list(range(5, max_stint_length, 5)),
"title": "Tyre Age",
},
yaxis_title=yaxis_title,
showlegend=False,
autosize=False,
Expand All @@ -341,9 +345,53 @@ def compounds_distplot(
fig = go.Figure()
yaxis_title = "Seconds to LRT" if y == "DeltaToLapRep" else "Percent from LRT"

_, palette, _, _ = _plot_args()
max_stint_length = 0

for compound in compounds:
compound_laps = included_laps[included_laps["Compound"] == compound]
# clip tyre life range to where there are at least three records
tyre_life_range = compound_laps.groupby("TyreLife").size()
tyre_life_range = tyre_life_range[tyre_life_range >= 3].index
max_stint_length = max(max_stint_length, tyre_life_range.max())

compound_laps = compound_laps[compound_laps["TyreLife"].isin(tyre_life_range)]

if violin_plot:
fig.add_trace(
go.Violin(
x=compound_laps["TyreLife"],
y=compound_laps[y],
fillcolor=palette[compound],
line={"color": palette[compound]},
name=compound,
opacity=1,
spanmode="soft",
)
)
else:
fig.add_trace(
go.Box(
x=compound_laps["TyreLife"],
y=compound_laps[y],
boxpoints="outliers",
pointpos=0,
fillcolor=palette[compound],
line={"color": "dimgray"},
name=compound,
showwhiskers=True,
)
)

fig.update_layout(
template="plotly_dark",
xaxis_title="Tyre Age",
boxmode="group",
violinmode="group",
xaxis={
"tickmode": "array",
"tickvals": list(range(5, max_stint_length, 5)),
"title": "Tyre Age",
},
yaxis_title=yaxis_title,
showlegend=False,
autosize=False,
Expand Down
19 changes: 13 additions & 6 deletions f1_visualization/plotly_dash/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ def lap_numbers_slider(slider_id: str, **kwargs) -> dcc.RangeSlider:
[
html.H4("Caveats", className="alert-heading"),
html.P(
"The above driver selection does not apply to this plot. "
"The driver selections does not apply to this plot. "
"This plot always considers laps driven by all drivers."
),
html.Hr(),
Expand All @@ -256,11 +256,14 @@ def lap_numbers_slider(slider_id: str, **kwargs) -> dcc.RangeSlider:
"As the same tyre may have been used in qualifying sessions."
),
html.Hr(),
html.P("Only compounds that completed at least one sixth of all laps are shown."),
html.P(
"Only compounds that completed at least one sixth of all laps are shown. "
"Outlier laps are filtered out."
),
html.Hr(),
html.P(
"For each compound, the range of shown tyre life is limited by "
"the number of drivers who complete a stint of that length. This is to avoid "
"the number of drivers who completed a stint of that length. This is to avoid "
"the plot being stretched by one driver doing a very long stint."
),
],
Expand All @@ -279,7 +282,11 @@ def lap_numbers_slider(slider_id: str, **kwargs) -> dcc.RangeSlider:
[
dbc.Col(
dcc.Dropdown(
options=["lineplot", "boxplot", "violinplot"],
options=[
{"label": "Lineplot", "value": "lineplot"},
{"label": "Boxplot", "value": "boxplot"},
{"label": "Violin Plot", "value": "violinplot"},
],
value="lineplot",
clearable=False,
placeholder="Select a plot type",
Expand All @@ -290,8 +297,8 @@ def lap_numbers_slider(slider_id: str, **kwargs) -> dcc.RangeSlider:
dbc.Col(
dcc.Dropdown(
options=[
{"label": "Show as seconds", "value": True},
{"label": "Show as percentage", "value": False},
{"label": "Show delta as seconds", "value": True},
{"label": "Show delta as percentages", "value": False},
],
value=True,
clearable=False,
Expand Down

0 comments on commit 6a6f217

Please sign in to comment.