ssscoring.notebook

Utility reusable code for notebooks.

  1# See: https://github.com/pr3d4t0r/SSScoring/blob/master/LICENSE.txt
  2
  3"""
  4## Utility reusable code for notebooks.
  5"""
  6
  7
  8from ssscoring.constants import DEFAULT_PLOT_MAX_V_SCALE
  9from ssscoring.constants import DEFAULT_SPEED_ACCURACY_SCALE
 10from ssscoring.constants import MAX_ALTITUDE_FT
 11from ssscoring.constants import SPEED_ACCURACY_THRESHOLD
 12from ssscoring.datatypes import PerformanceWindow
 13from ssscoring.errors import SSScoringError
 14
 15import bokeh.models as bm
 16import bokeh.plotting as bp
 17import pandas as pd
 18
 19
 20# *** constants ***
 21
 22DEFAULT_AXIS_COLOR_BOKEH = 'lightsteelblue'
 23"""
 24CSS color name for the axis colors used in notebooks and Streamlit
 25with Bokeh.
 26"""
 27
 28
 29# Ref:  https://www.w3schools.com/colors/colors_groups.asp
 30# Ref: https://docs.bokeh.org/en/latest/docs/reference/colors.html#module-bokeh.colors
 31SPEED_COLORS = colors = ('#32cd32', '#0000ff', '#ff6347', '#40e0d0', '#00bfff', '#22b822', '#ff7f50', '#008b8b',)
 32"""
 33Colors used for tracking the lines in a multi-jump plot, so that each track is
 34associated with a different color and easier to visualize.  8 distinct colors,
 35corresponding to each jump in a competition.
 36"""
 37
 38
 39# *** functions ***
 40
 41def initializePlot(jumpTitle: str,
 42                   height=500,
 43                   width=900,
 44                   xLabel='seconds from exit',
 45                   yLabel='km/h',
 46                   xMax=35.0,
 47                   yMax=DEFAULT_PLOT_MAX_V_SCALE,
 48                   backgroundColorName='#1a1a1a',
 49                   colorName=DEFAULT_AXIS_COLOR_BOKEH):
 50    """
 51    Initiialize a plotting area for notebook output.
 52
 53    Arguments
 54    ---------
 55        jumpTitle: str
 56    A title to identify the plot.
 57
 58        height: int
 59    Height of the plot in pixels.  Default = 500.
 60
 61        width: int
 62    Width of the plot in pixels.  Default = 900.
 63
 64        xLabel: str
 65    X axis label.  Default:  `'seconds from exit'`
 66
 67        yLabel: str
 68    Y axis label.  Default:  `'km/h'`
 69
 70        xMax: float
 71    The maximum rnage for the X axis.  Default = 40.0
 72
 73        yMax: float
 74    The maximum range for the Y axis.  Default = `DEFAULT_PLOT_MAX_V_SCALE`
 75
 76        backgroundColorName
 77    A string with the CSS RGB value of the background color or its CSS color
 78    string name.
 79
 80        colorName
 81    A valid CSS color string.
 82    """
 83    # bi.curdoc().theme = 'dark_minimal'
 84    plot = bp.figure(title=jumpTitle,
 85                     height=height,
 86                     width=width,
 87                     x_axis_label=xLabel,
 88                     y_axis_label=yLabel,
 89                     x_range=(0.0, xMax),
 90                     y_range=(0.0, yMax),
 91                     background_fill_color=backgroundColorName,
 92                     border_fill_color=backgroundColorName
 93                     )
 94    plot.xaxis.axis_label_text_color=colorName
 95    plot.xaxis.major_label_text_color=colorName
 96    plot.xaxis.axis_line_color=colorName
 97    plot.xaxis.major_tick_line_color=colorName
 98    plot.xaxis.minor_tick_line_color=colorName
 99    plot.yaxis.axis_label_text_color=colorName
100    plot.yaxis.major_label_text_color=colorName
101    plot.yaxis.axis_line_color=colorName
102    plot.yaxis.major_tick_line_color=colorName
103    plot.yaxis.minor_tick_line_color=colorName
104    plot.title.text_color = colorName
105    return plot
106
107
108def _graphSegment(plot,
109                  x0=0.0,
110                  y0=0.0,
111                  x1=0.0,
112                  y1=0.0,
113                  lineWidth=1,
114                  color='black'):
115    plot.segment(x0=[ x0, ],
116                 y0=[ y0, ],
117                 x1=[ x1, ],
118                 y1=[ y1, ],
119                 line_width=lineWidth,
120                 color=color)
121
122
123def _initLinearAxis(label: str,
124                    rangeName: str,
125                    colorName: str=DEFAULT_AXIS_COLOR_BOKEH) -> bm.LinearAxis:
126    """
127    Make a linear initialized to use standard colors with Bokeh plots.
128
129    Arguments
130    ---------
131
132        label: str
133    The axis label, text string.
134
135        rangeName
136    The range name, often used for specifying the measurment units.
137
138        colorName
139    A valid CSS color string.
140
141    Return
142    ------
143    An instance of `bokeh.models.LinearAxis`.
144    """
145    linearAxis = bm.LinearAxis(
146            axis_label = label,
147            axis_label_text_color = colorName,
148            axis_line_color = colorName,
149            major_label_text_color = colorName,
150            major_tick_line_color=colorName,
151            minor_tick_line_color=colorName,
152            y_range_name = rangeName,
153    )
154    return linearAxis
155
156
157def initializeExtraYRanges(plot,
158                           startY: float = 0.0,
159                           endY: float = MAX_ALTITUDE_FT,
160                           maxSpeedAccuracy: float | None = None):
161    """
162    Initialize an extra Y range for reporting other data trend (e.g. altitude)
163    in the plot.
164
165    Arguments
166    ---------
167        plot
168    A valid instance of `bp.figure` with an existing plot defined for it
169
170        startY: float
171    The Y range starting value
172
173        endY: float
174    The Y range ending value
175
176        maxSpeedAccuracy: float
177    Maximum speed accuracy value to determine the range of the speed accuracy axis.
178    If None or < SPEED_ACCURACY_THRESHOLD, range is 0-10. Otherwise, range is 0-maxSpeedAccuracy*1.1
179
180    Returns
181    -------
182    An instance of `bp.figure` updated to report an additional Y axis.
183    """
184    speedAccuracyEnd = DEFAULT_SPEED_ACCURACY_SCALE
185    if maxSpeedAccuracy is not None and maxSpeedAccuracy >= SPEED_ACCURACY_THRESHOLD:
186        speedAccuracyEnd = maxSpeedAccuracy * 1.1
187    plot.extra_y_ranges = {
188        'altitudeFt': bm.Range1d(start = startY, end = endY),
189        'angle': bm.Range1d(start = 0.0, end = 90.0),
190        'speedAccuracy': bm.Range1d(start = 0.0, end = speedAccuracyEnd),
191    }
192    plot.add_layout(_initLinearAxis('Alt (ft)', 'altitudeFt', colorName=DEFAULT_AXIS_COLOR_BOKEH), 'left')
193    plot.add_layout(_initLinearAxis('angle', 'angle', colorName=DEFAULT_AXIS_COLOR_BOKEH), 'left')
194    plot.add_layout(_initLinearAxis('Speed accuracy ISC', 'speedAccuracy', colorName=DEFAULT_AXIS_COLOR_BOKEH), 'left')
195    return plot
196
197
198def validationWindowDataFrom(data: pd.DataFrame, window: PerformanceWindow) -> bm.ColumnDataSource:
199    """
200    Generate the validation window dataset for plotting the ISC speed accuracy
201    values.  It's a subset defined from the end of the scoring window to the
202    validation start.
203
204    Arguments
205    ---------
206        data
207    A dataframe with the `plotTime` column set, with all the jump data, after
208    speed validation processing.
209
210        window
211    A `ssscoring.datatypes.PerformanceWindow` instance, with the `validationStart`
212    value initialized.
213
214    Returns
215    -------
216    A column data source ready for plotting the Y-values of a Bokeh chart.
217    """
218    validationData = data[data.altitudeAGL <= window.validationStart]
219    return bm.ColumnDataSource({ 'x': validationData.plotTime, 'y': validationData.speedAccuracyISC, })
220
221
222def _plotSpeedAccuracy(plot, data, window):
223    accuracyDataSource = validationWindowDataFrom(data, window)
224    plot.line('x', 'y', y_range_name='speedAccuracy', legend_label='Speed accuracy ISC', line_width=5.0, line_color='lime', source=accuracyDataSource)
225
226    validationData = data[data.altitudeAGL <= window.validationStart]
227    plot.line(x = validationData.plotTime, y = pd.Series([ SPEED_ACCURACY_THRESHOLD, ]*len(validationData)), y_range_name='speedAccuracy', line_dash='dashed', line_color='lime', line_width=1.0)
228
229
230def graphJumpResult(plot,
231                    jumpResult,
232                    lineColor = 'green',
233                    legend = 'speed',
234                    showIt = True,
235                    showAccuracy = True):
236    """
237    Graph the jump results using the initialized plot.
238
239    Arguments
240    ---------
241        plot: bp.figure
242    A Bokeh figure where to render the plot.
243
244        jumpResult: ssscoring.JumpResults
245    A jump results named tuple with score, max speed, scores, data, etc.
246
247        lineColor: str
248    A valid color from the Bokeh palette:  https://docs.bokeh.org/en/2.1.1/docs/reference/colors.html
249    This module defines 8 colors for rendering a competition's results.  See:
250    `ssscoring.notebook.SPEED_COLORS` for the list.
251
252        legend: str
253    A title for the plot.
254
255        showIt: bool
256    A boolean flag for whether the call should render the max speed, time,
257    horizontal speed, etc. in the current plot.  This is used for discriminating
258    between single jump plots and plotting only the speed for the aggregate
259    plot display for a competition or training session.
260
261    To display the actual plot, use `bp.show(plot)` if running from Lucyfer/Jupyter
262    or use `st.bokeh_chart(plot)` if in the Streamlit environment.
263
264    ```python
265    # Basic usage showing speed accuracy overlay
266    graphJumpResult(plot, result)
267    bp.show(plot)
268
269    # Multiple jumps without speed accuracy overlay
270    for result in jumpResults:
271        graphJumpResult(plot, result, showIt=False, showAccuracy=False)
272    bp.show(plot)
273    ```
274    Another alternative use is in Streamlit.io applications:
275
276    ```python
277    # Streamlit app with speed accuracy overlay
278    graphJumpResult(plot, result, showIt=False)
279    st.bokeh_chart(plot, use_container_width=True)
280    ```
281
282    Returns
283    -------
284    `None`.
285    """
286    if jumpResult.data is not None:
287        data = jumpResult.data
288        scores = jumpResult.scores
289        score = jumpResult.score
290        # Main speed line
291        plot.line(data.plotTime, data.vKMh, legend_label = legend, line_width = 2, line_color = lineColor)
292
293        if showIt:
294            maxSpeed = data.vKMh.max()
295            t = data[data.vKMh == maxSpeed].iloc[0].plotTime
296            plot.line(data.plotTime, data.hKMh, legend_label = 'H-speed', line_width = 2, line_color = 'red')
297            _plotSpeedAccuracy(plot, data, jumpResult.window)
298            if scores != None:
299                _graphSegment(plot, scores[score]+3.0, 0.0, scores[score]+3.0, score, 1, 'darkseagreen')
300                _graphSegment(plot, scores[score], 0.0, scores[score], score, 1, 'darkseagreen')
301                plot.scatter(x = [ scores[score]+1.5, ], y = [ score, ], marker = 'circle_cross', size = [ 15, ], line_color = 'limegreen', fill_color = 'darkgreen', line_width = 2)
302                plot.scatter(x = [ t, ], y = [ maxSpeed, ], marker = 'diamond_dot', size = [ 20, ], line_color = 'yellow', fill_color = 'red', line_width = 2)
303
304
305def graphAltitude(plot,
306                  jumpResult,
307                  label = 'Alt (ft)',
308                  lineColor = 'palegoldenrod',
309                  rangeName = 'altitudeFt'):
310    """
311    Graph a vertical axis with additional data, often used for altitude in ft
312    ASL.
313
314    Arguments
315    ---------
316        plot: pb.figure
317    A Bokeh figure where to render the plot.
318
319        jumpResult: ssscoring.JumpResults
320    A jump results named tuple with score, max speed, scores, data, etc.
321
322        label: str
323    The legend label for the new Y axis.
324
325        lineColor: str
326    A color name from the Bokeh palette.
327
328        rangeName: str
329    The range name to associate the `LinearAxis` layout with the data for
330    plotting.
331
332    Returns
333    -------
334    `None`.
335    """
336    data = jumpResult.data
337    plot.line(data.plotTime, data.altitudeAGLFt, legend_label = label, line_width = 2, line_color = lineColor, y_range_name = rangeName)
338
339
340def graphAngle(plot,
341               jumpResult,
342               label = 'angle',
343               lineColor = 'deepskyblue',
344               rangeName = 'angle'):
345    """
346    Graph the flight angle
347
348    Arguments
349    ---------
350        plot: pb.figure
351    A Bokeh figure where to render the plot.
352
353        jumpResult: ssscoring.JumpResults
354    A jump results named tuple with score, max speed, scores, data, etc.
355
356        label: str
357    The legend label for the new Y axis.
358
359        lineColor: str
360    A color name from the Bokeh palette.
361
362        rangeName: str
363    The range name to associate the `LinearAxis` layout with the data for
364    plotting.
365
366    Returns
367    -------
368    `None`.
369    """
370    data = jumpResult.data
371    plot.line(data.plotTime, data.speedAngle, legend_label = label, line_width = 2, line_color = lineColor, y_range_name = rangeName)
372
373
374def convertHexColorToRGB(color: str) -> list:
375    """
376    Converts a color in the format `#a0b1c2` to its RGB equivalent as a list
377    of three values 0-255.
378
379    Arguments
380    ---------
381        color
382    A `str` in the form '#xxyyzz` where xx, yy, and zz are values in the hex
383    range 00-FF.  color is case insensitive.
384
385    Returns
386    -------
387    A list of 3 integers, each in the range 0-255 corresponding to the hex
388    color value.
389
390    Raises
391    ------
392    `SSScoringError' if `color` is an invalid hex-encoded textual RGB value.
393    The string value of the exception describes the error cause.
394
395    `ValueError` if the characters that make the hex value are not in the
396    range 0-9, a-f.
397    """
398    if not isinstance(color, str):
399        raise TypeError('Invalid color type - must be str')
400    color = color.replace('#', '')
401    if len(color) != 6:
402        raise SSScoringError('Invalid hex value length')
403    result = [ int(color[x:x+2], 16) for x in range(0, len(color), 2) ]
404    return result
DEFAULT_AXIS_COLOR_BOKEH = 'lightsteelblue'

CSS color name for the axis colors used in notebooks and Streamlit with Bokeh.

def initializePlot( jumpTitle: str, height=500, width=900, xLabel='seconds from exit', yLabel='km/h', xMax=35.0, yMax=550.0, backgroundColorName='#1a1a1a', colorName='lightsteelblue'):
 42def initializePlot(jumpTitle: str,
 43                   height=500,
 44                   width=900,
 45                   xLabel='seconds from exit',
 46                   yLabel='km/h',
 47                   xMax=35.0,
 48                   yMax=DEFAULT_PLOT_MAX_V_SCALE,
 49                   backgroundColorName='#1a1a1a',
 50                   colorName=DEFAULT_AXIS_COLOR_BOKEH):
 51    """
 52    Initiialize a plotting area for notebook output.
 53
 54    Arguments
 55    ---------
 56        jumpTitle: str
 57    A title to identify the plot.
 58
 59        height: int
 60    Height of the plot in pixels.  Default = 500.
 61
 62        width: int
 63    Width of the plot in pixels.  Default = 900.
 64
 65        xLabel: str
 66    X axis label.  Default:  `'seconds from exit'`
 67
 68        yLabel: str
 69    Y axis label.  Default:  `'km/h'`
 70
 71        xMax: float
 72    The maximum rnage for the X axis.  Default = 40.0
 73
 74        yMax: float
 75    The maximum range for the Y axis.  Default = `DEFAULT_PLOT_MAX_V_SCALE`
 76
 77        backgroundColorName
 78    A string with the CSS RGB value of the background color or its CSS color
 79    string name.
 80
 81        colorName
 82    A valid CSS color string.
 83    """
 84    # bi.curdoc().theme = 'dark_minimal'
 85    plot = bp.figure(title=jumpTitle,
 86                     height=height,
 87                     width=width,
 88                     x_axis_label=xLabel,
 89                     y_axis_label=yLabel,
 90                     x_range=(0.0, xMax),
 91                     y_range=(0.0, yMax),
 92                     background_fill_color=backgroundColorName,
 93                     border_fill_color=backgroundColorName
 94                     )
 95    plot.xaxis.axis_label_text_color=colorName
 96    plot.xaxis.major_label_text_color=colorName
 97    plot.xaxis.axis_line_color=colorName
 98    plot.xaxis.major_tick_line_color=colorName
 99    plot.xaxis.minor_tick_line_color=colorName
100    plot.yaxis.axis_label_text_color=colorName
101    plot.yaxis.major_label_text_color=colorName
102    plot.yaxis.axis_line_color=colorName
103    plot.yaxis.major_tick_line_color=colorName
104    plot.yaxis.minor_tick_line_color=colorName
105    plot.title.text_color = colorName
106    return plot

Initiialize a plotting area for notebook output.

Arguments

jumpTitle: str

A title to identify the plot.

height: int

Height of the plot in pixels. Default = 500.

width: int

Width of the plot in pixels. Default = 900.

xLabel: str

X axis label. Default: 'seconds from exit'

yLabel: str

Y axis label. Default: 'km/h'

xMax: float

The maximum rnage for the X axis. Default = 40.0

yMax: float

The maximum range for the Y axis. Default = DEFAULT_PLOT_MAX_V_SCALE

backgroundColorName

A string with the CSS RGB value of the background color or its CSS color string name.

colorName

A valid CSS color string.

def initializeExtraYRanges( plot, startY: float = 0.0, endY: float = 14000.0, maxSpeedAccuracy: float | None = None):
158def initializeExtraYRanges(plot,
159                           startY: float = 0.0,
160                           endY: float = MAX_ALTITUDE_FT,
161                           maxSpeedAccuracy: float | None = None):
162    """
163    Initialize an extra Y range for reporting other data trend (e.g. altitude)
164    in the plot.
165
166    Arguments
167    ---------
168        plot
169    A valid instance of `bp.figure` with an existing plot defined for it
170
171        startY: float
172    The Y range starting value
173
174        endY: float
175    The Y range ending value
176
177        maxSpeedAccuracy: float
178    Maximum speed accuracy value to determine the range of the speed accuracy axis.
179    If None or < SPEED_ACCURACY_THRESHOLD, range is 0-10. Otherwise, range is 0-maxSpeedAccuracy*1.1
180
181    Returns
182    -------
183    An instance of `bp.figure` updated to report an additional Y axis.
184    """
185    speedAccuracyEnd = DEFAULT_SPEED_ACCURACY_SCALE
186    if maxSpeedAccuracy is not None and maxSpeedAccuracy >= SPEED_ACCURACY_THRESHOLD:
187        speedAccuracyEnd = maxSpeedAccuracy * 1.1
188    plot.extra_y_ranges = {
189        'altitudeFt': bm.Range1d(start = startY, end = endY),
190        'angle': bm.Range1d(start = 0.0, end = 90.0),
191        'speedAccuracy': bm.Range1d(start = 0.0, end = speedAccuracyEnd),
192    }
193    plot.add_layout(_initLinearAxis('Alt (ft)', 'altitudeFt', colorName=DEFAULT_AXIS_COLOR_BOKEH), 'left')
194    plot.add_layout(_initLinearAxis('angle', 'angle', colorName=DEFAULT_AXIS_COLOR_BOKEH), 'left')
195    plot.add_layout(_initLinearAxis('Speed accuracy ISC', 'speedAccuracy', colorName=DEFAULT_AXIS_COLOR_BOKEH), 'left')
196    return plot

Initialize an extra Y range for reporting other data trend (e.g. altitude) in the plot.

Arguments

plot

A valid instance of bp.figure with an existing plot defined for it

startY: float

The Y range starting value

endY: float

The Y range ending value

maxSpeedAccuracy: float

Maximum speed accuracy value to determine the range of the speed accuracy axis. If None or < SPEED_ACCURACY_THRESHOLD, range is 0-10. Otherwise, range is 0-maxSpeedAccuracy*1.1

Returns

An instance of bp.figure updated to report an additional Y axis.

def validationWindowDataFrom( data: pandas.core.frame.DataFrame, window: ssscoring.datatypes.PerformanceWindow) -> bokeh.models.sources.ColumnDataSource:
199def validationWindowDataFrom(data: pd.DataFrame, window: PerformanceWindow) -> bm.ColumnDataSource:
200    """
201    Generate the validation window dataset for plotting the ISC speed accuracy
202    values.  It's a subset defined from the end of the scoring window to the
203    validation start.
204
205    Arguments
206    ---------
207        data
208    A dataframe with the `plotTime` column set, with all the jump data, after
209    speed validation processing.
210
211        window
212    A `ssscoring.datatypes.PerformanceWindow` instance, with the `validationStart`
213    value initialized.
214
215    Returns
216    -------
217    A column data source ready for plotting the Y-values of a Bokeh chart.
218    """
219    validationData = data[data.altitudeAGL <= window.validationStart]
220    return bm.ColumnDataSource({ 'x': validationData.plotTime, 'y': validationData.speedAccuracyISC, })

Generate the validation window dataset for plotting the ISC speed accuracy values. It's a subset defined from the end of the scoring window to the validation start.

Arguments

data

A dataframe with the plotTime column set, with all the jump data, after speed validation processing.

window

A ssscoring.datatypes.PerformanceWindow instance, with the validationStart value initialized.

Returns

A column data source ready for plotting the Y-values of a Bokeh chart.

def graphJumpResult( plot, jumpResult, lineColor='green', legend='speed', showIt=True, showAccuracy=True):
231def graphJumpResult(plot,
232                    jumpResult,
233                    lineColor = 'green',
234                    legend = 'speed',
235                    showIt = True,
236                    showAccuracy = True):
237    """
238    Graph the jump results using the initialized plot.
239
240    Arguments
241    ---------
242        plot: bp.figure
243    A Bokeh figure where to render the plot.
244
245        jumpResult: ssscoring.JumpResults
246    A jump results named tuple with score, max speed, scores, data, etc.
247
248        lineColor: str
249    A valid color from the Bokeh palette:  https://docs.bokeh.org/en/2.1.1/docs/reference/colors.html
250    This module defines 8 colors for rendering a competition's results.  See:
251    `ssscoring.notebook.SPEED_COLORS` for the list.
252
253        legend: str
254    A title for the plot.
255
256        showIt: bool
257    A boolean flag for whether the call should render the max speed, time,
258    horizontal speed, etc. in the current plot.  This is used for discriminating
259    between single jump plots and plotting only the speed for the aggregate
260    plot display for a competition or training session.
261
262    To display the actual plot, use `bp.show(plot)` if running from Lucyfer/Jupyter
263    or use `st.bokeh_chart(plot)` if in the Streamlit environment.
264
265    ```python
266    # Basic usage showing speed accuracy overlay
267    graphJumpResult(plot, result)
268    bp.show(plot)
269
270    # Multiple jumps without speed accuracy overlay
271    for result in jumpResults:
272        graphJumpResult(plot, result, showIt=False, showAccuracy=False)
273    bp.show(plot)
274    ```
275    Another alternative use is in Streamlit.io applications:
276
277    ```python
278    # Streamlit app with speed accuracy overlay
279    graphJumpResult(plot, result, showIt=False)
280    st.bokeh_chart(plot, use_container_width=True)
281    ```
282
283    Returns
284    -------
285    `None`.
286    """
287    if jumpResult.data is not None:
288        data = jumpResult.data
289        scores = jumpResult.scores
290        score = jumpResult.score
291        # Main speed line
292        plot.line(data.plotTime, data.vKMh, legend_label = legend, line_width = 2, line_color = lineColor)
293
294        if showIt:
295            maxSpeed = data.vKMh.max()
296            t = data[data.vKMh == maxSpeed].iloc[0].plotTime
297            plot.line(data.plotTime, data.hKMh, legend_label = 'H-speed', line_width = 2, line_color = 'red')
298            _plotSpeedAccuracy(plot, data, jumpResult.window)
299            if scores != None:
300                _graphSegment(plot, scores[score]+3.0, 0.0, scores[score]+3.0, score, 1, 'darkseagreen')
301                _graphSegment(plot, scores[score], 0.0, scores[score], score, 1, 'darkseagreen')
302                plot.scatter(x = [ scores[score]+1.5, ], y = [ score, ], marker = 'circle_cross', size = [ 15, ], line_color = 'limegreen', fill_color = 'darkgreen', line_width = 2)
303                plot.scatter(x = [ t, ], y = [ maxSpeed, ], marker = 'diamond_dot', size = [ 20, ], line_color = 'yellow', fill_color = 'red', line_width = 2)

Graph the jump results using the initialized plot.

Arguments

plot: bp.figure

A Bokeh figure where to render the plot.

jumpResult: ssscoring.JumpResults

A jump results named tuple with score, max speed, scores, data, etc.

lineColor: str

A valid color from the Bokeh palette: https://docs.bokeh.org/en/2.1.1/docs/reference/colors.html This module defines 8 colors for rendering a competition's results. See: ssscoring.notebook.SPEED_COLORS for the list.

legend: str

A title for the plot.

showIt: bool

A boolean flag for whether the call should render the max speed, time, horizontal speed, etc. in the current plot. This is used for discriminating between single jump plots and plotting only the speed for the aggregate plot display for a competition or training session.

To display the actual plot, use bp.show(plot) if running from Lucyfer/Jupyter or use st.bokeh_chart(plot) if in the Streamlit environment.

# Basic usage showing speed accuracy overlay
graphJumpResult(plot, result)
bp.show(plot)

# Multiple jumps without speed accuracy overlay
for result in jumpResults:
    graphJumpResult(plot, result, showIt=False, showAccuracy=False)
bp.show(plot)

Another alternative use is in Streamlit.io applications:

# Streamlit app with speed accuracy overlay
graphJumpResult(plot, result, showIt=False)
st.bokeh_chart(plot, use_container_width=True)

Returns

None.

def graphAltitude( plot, jumpResult, label='Alt (ft)', lineColor='palegoldenrod', rangeName='altitudeFt'):
306def graphAltitude(plot,
307                  jumpResult,
308                  label = 'Alt (ft)',
309                  lineColor = 'palegoldenrod',
310                  rangeName = 'altitudeFt'):
311    """
312    Graph a vertical axis with additional data, often used for altitude in ft
313    ASL.
314
315    Arguments
316    ---------
317        plot: pb.figure
318    A Bokeh figure where to render the plot.
319
320        jumpResult: ssscoring.JumpResults
321    A jump results named tuple with score, max speed, scores, data, etc.
322
323        label: str
324    The legend label for the new Y axis.
325
326        lineColor: str
327    A color name from the Bokeh palette.
328
329        rangeName: str
330    The range name to associate the `LinearAxis` layout with the data for
331    plotting.
332
333    Returns
334    -------
335    `None`.
336    """
337    data = jumpResult.data
338    plot.line(data.plotTime, data.altitudeAGLFt, legend_label = label, line_width = 2, line_color = lineColor, y_range_name = rangeName)

Graph a vertical axis with additional data, often used for altitude in ft ASL.

Arguments

plot: pb.figure

A Bokeh figure where to render the plot.

jumpResult: ssscoring.JumpResults

A jump results named tuple with score, max speed, scores, data, etc.

label: str

The legend label for the new Y axis.

lineColor: str

A color name from the Bokeh palette.

rangeName: str

The range name to associate the LinearAxis layout with the data for plotting.

Returns

None.

def graphAngle( plot, jumpResult, label='angle', lineColor='deepskyblue', rangeName='angle'):
341def graphAngle(plot,
342               jumpResult,
343               label = 'angle',
344               lineColor = 'deepskyblue',
345               rangeName = 'angle'):
346    """
347    Graph the flight angle
348
349    Arguments
350    ---------
351        plot: pb.figure
352    A Bokeh figure where to render the plot.
353
354        jumpResult: ssscoring.JumpResults
355    A jump results named tuple with score, max speed, scores, data, etc.
356
357        label: str
358    The legend label for the new Y axis.
359
360        lineColor: str
361    A color name from the Bokeh palette.
362
363        rangeName: str
364    The range name to associate the `LinearAxis` layout with the data for
365    plotting.
366
367    Returns
368    -------
369    `None`.
370    """
371    data = jumpResult.data
372    plot.line(data.plotTime, data.speedAngle, legend_label = label, line_width = 2, line_color = lineColor, y_range_name = rangeName)

Graph the flight angle

Arguments

plot: pb.figure

A Bokeh figure where to render the plot.

jumpResult: ssscoring.JumpResults

A jump results named tuple with score, max speed, scores, data, etc.

label: str

The legend label for the new Y axis.

lineColor: str

A color name from the Bokeh palette.

rangeName: str

The range name to associate the LinearAxis layout with the data for plotting.

Returns

None.

def convertHexColorToRGB(color: str) -> list:
375def convertHexColorToRGB(color: str) -> list:
376    """
377    Converts a color in the format `#a0b1c2` to its RGB equivalent as a list
378    of three values 0-255.
379
380    Arguments
381    ---------
382        color
383    A `str` in the form '#xxyyzz` where xx, yy, and zz are values in the hex
384    range 00-FF.  color is case insensitive.
385
386    Returns
387    -------
388    A list of 3 integers, each in the range 0-255 corresponding to the hex
389    color value.
390
391    Raises
392    ------
393    `SSScoringError' if `color` is an invalid hex-encoded textual RGB value.
394    The string value of the exception describes the error cause.
395
396    `ValueError` if the characters that make the hex value are not in the
397    range 0-9, a-f.
398    """
399    if not isinstance(color, str):
400        raise TypeError('Invalid color type - must be str')
401    color = color.replace('#', '')
402    if len(color) != 6:
403        raise SSScoringError('Invalid hex value length')
404    result = [ int(color[x:x+2], 16) for x in range(0, len(color), 2) ]
405    return result

Converts a color in the format #a0b1c2 to its RGB equivalent as a list of three values 0-255.

Arguments

color

A str in the form '#xxyyzz` where xx, yy, and zz are values in the hex range 00-FF. color is case insensitive.

Returns

A list of 3 integers, each in the range 0-255 corresponding to the hex color value.

Raises

SSScoringError' ifcolor` is an invalid hex-encoded textual RGB value. The string value of the exception describes the error cause.

ValueError if the characters that make the hex value are not in the range 0-9, a-f.