Skip to content

Commit b0ae86b

Browse files
committed
SkiRunDifficulty.colormap convention support
1 parent 5585ead commit b0ae86b

File tree

2 files changed

+84
-28
lines changed

2 files changed

+84
-28
lines changed

openskistats/models.py

Lines changed: 79 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
https://github.com/russellporter/openskidata-format
44
"""
55

6+
from dataclasses import dataclass
67
from enum import StrEnum
78
from typing import Annotated, Literal
89

@@ -36,6 +37,36 @@ class SkiRunConvention(StrEnum):
3637
japan = "japan"
3738

3839

40+
@dataclass
41+
class _SkiRunColors:
42+
green: str
43+
blue: str
44+
red: str
45+
black: str
46+
orange: str
47+
gray: str
48+
49+
50+
# from https://github.com/russellporter/openskidata-format/blob/e421ef0a0814437c362611e07cb43c32bac4172c/src/Run.ts#L87-L92
51+
ski_run_colors_bright = _SkiRunColors(
52+
green="#00a80e",
53+
blue="#005aa8",
54+
red="#f8161a",
55+
black="#000000",
56+
orange="#ff9100",
57+
gray="#595959",
58+
)
59+
60+
ski_run_colors_subtle = _SkiRunColors(
61+
green="#badbb8",
62+
blue="#a1a1d8",
63+
red="#ff8c8e",
64+
black="#828282",
65+
orange="#e5c47e",
66+
gray="#d9d9d9",
67+
)
68+
69+
3970
class SkiRunDifficulty(StrEnum):
4071
"""
4172
https://wiki.openstreetmap.org/wiki/Key:piste:difficulty
@@ -76,35 +107,53 @@ def condensed_values(cls) -> "list[SkiRunDifficulty]":
76107

77108
@classmethod
78109
def colormap(
79-
cls, condense: bool = False, subtle: bool = True
110+
cls,
111+
condense: bool = False,
112+
subtle: bool = True,
113+
convention: SkiRunConvention = SkiRunConvention.north_america,
80114
) -> "dict[SkiRunDifficulty, str]":
81115
"""
82-
Difficulty to color mapping based on North American conventions.
83-
https://www.nsaa.org/NSAA/Safety/Trail_Signage/NSAA/Safety/Trail_Signage.aspx
116+
Difficulty to color mapping according to the local convention.
117+
See:
118+
<https://github.com/russellporter/openskidata-format/blob/e421ef0a0814437c362611e07cb43c32bac4172c/src/Run.ts#L113-L166>
119+
<https://www.nsaa.org/NSAA/Safety/Trail_Signage/NSAA/Safety/Trail_Signage.aspx>
84120
"""
85-
colormap = (
86-
{
87-
cls.novice: "#badbb8",
88-
cls.easy: "#badbb8",
89-
cls.intermediate: "#a1a1d8",
90-
cls.advanced: "#828282",
91-
cls.expert: "#828282",
92-
cls.extreme: "#828282",
93-
cls.freeride: "#828282", # considered "#e5c47e"
94-
cls.other: "#d9d9d9",
121+
colors = ski_run_colors_subtle if subtle else ski_run_colors_bright
122+
if convention == SkiRunConvention.north_america:
123+
colormap = {
124+
cls.novice: colors.green,
125+
cls.easy: colors.green,
126+
cls.intermediate: colors.blue,
127+
cls.advanced: colors.black,
128+
cls.expert: colors.black,
129+
cls.extreme: colors.orange,
130+
cls.freeride: colors.orange,
131+
cls.other: colors.gray,
132+
}
133+
elif convention == SkiRunConvention.europe:
134+
colormap = {
135+
cls.novice: colors.green,
136+
cls.easy: colors.blue,
137+
cls.intermediate: colors.red,
138+
cls.advanced: colors.black,
139+
cls.expert: colors.black,
140+
cls.extreme: colors.orange,
141+
cls.freeride: colors.orange,
142+
cls.other: colors.gray,
95143
}
96-
if subtle
97-
else {
98-
cls.novice: "#60A45C",
99-
cls.easy: "#60A45C",
100-
cls.intermediate: "#3E7DBF",
101-
cls.advanced: "#000000",
102-
cls.expert: "#000000",
103-
cls.extreme: "#000000",
104-
cls.freeride: "#000000", # considered "#DEB251"
105-
cls.other: "#bfbfbf",
144+
elif convention == SkiRunConvention.japan:
145+
colormap = {
146+
cls.novice: colors.green,
147+
cls.easy: colors.green,
148+
cls.intermediate: colors.red,
149+
cls.advanced: colors.black,
150+
cls.expert: colors.black,
151+
cls.extreme: colors.orange,
152+
cls.freeride: colors.orange,
153+
cls.other: colors.gray,
106154
}
107-
)
155+
else:
156+
raise ValueError(f"Unsupported run coloring convention: {convention}")
108157
if condense:
109158
colormap = {
110159
key: value
@@ -113,9 +162,13 @@ def colormap(
113162
}
114163
return colormap
115164

116-
def color(self, subtle: bool = False) -> str:
165+
def color(
166+
self,
167+
subtle: bool = True,
168+
convention: SkiRunConvention = SkiRunConvention.north_america,
169+
) -> str:
117170
"""Get the color for the difficulty level."""
118-
return self.colormap(subtle=subtle)[self]
171+
return self.colormap(subtle=subtle, convention=convention)[self]
119172

120173
@classmethod
121174
def markdown_description(cls, mode: Literal["phrase", "list"] = "phrase") -> str:

openskistats/plot_runs.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
cut_bearings_pl,
1313
get_cut_bearing_bins_df,
1414
)
15-
from openskistats.models import SkiRunDifficulty
15+
from openskistats.models import SkiRunConvention, SkiRunDifficulty
1616
from openskistats.plot import NARROW_SPACE, _add_polar_y_ticks
1717
from openskistats.utils import (
1818
pl_condense_run_difficulty,
@@ -315,6 +315,7 @@ def plot_bearing_by_latitude_bin() -> plt.Figure:
315315

316316
def plot_run_difficulty_histograms_by_slope(
317317
condense_difficulty: bool = False,
318+
convention: SkiRunConvention = SkiRunConvention.north_america,
318319
) -> pn.ggplot:
319320
difficulty_col = (
320321
"run_difficulty_condensed" if condense_difficulty else "run_difficulty"
@@ -364,7 +365,9 @@ def plot_run_difficulty_histograms_by_slope(
364365
)
365366
)
366367
)
367-
colormap = SkiRunDifficulty.colormap(condense=condense_difficulty, subtle=True)
368+
colormap = SkiRunDifficulty.colormap(
369+
condense=condense_difficulty, subtle=True, convention=convention
370+
)
368371
return (
369372
pn.ggplot(
370373
data=run_stats,

0 commit comments

Comments
 (0)