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        'vAccelMS2': bm.Range1d(start = 0.0, end = 15.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('Vertical acceleration m/s²', 'vAccelMS2', colorName=DEFAULT_AXIS_COLOR_BOKEH), 'left')
196    plot.add_layout(_initLinearAxis('Speed accuracy ISC', 'speedAccuracy', colorName=DEFAULT_AXIS_COLOR_BOKEH), 'left')
197    return plot
198
199
200def validationWindowDataFrom(data: pd.DataFrame, window: PerformanceWindow) -> bm.ColumnDataSource:
201    """
202    Generate the validation window dataset for plotting the ISC speed accuracy
203    values.  It's a subset defined from the end of the scoring window to the
204    validation start.
205
206    Arguments
207    ---------
208        data
209    A dataframe with the `plotTime` column set, with all the jump data, after
210    speed validation processing.
211
212        window
213    A `ssscoring.datatypes.PerformanceWindow` instance, with the `validationStart`
214    value initialized.
215
216    Returns
217    -------
218    A column data source ready for plotting the Y-values of a Bokeh chart.
219    """
220    validationData = data[data.altitudeAGL <= window.validationStart]
221    return bm.ColumnDataSource({ 'x': validationData.plotTime, 'y': validationData.speedAccuracyISC, })
222
223
224def _plotSpeedAccuracy(plot, data, window):
225    accuracyDataSource = validationWindowDataFrom(data, window)
226    plot.line('x', 'y', y_range_name='speedAccuracy', legend_label='Speed accuracy ISC', line_width=5.0, line_color='lime', source=accuracyDataSource)
227
228    validationData = data[data.altitudeAGL <= window.validationStart]
229    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)
230
231
232def graphJumpResult(plot,
233                    jumpResult,
234                    lineColor = 'green',
235                    legend = 'speed',
236                    showIt = True,
237                    showAccuracy = True):
238    """
239    Graph the jump results using the initialized plot.
240
241    Arguments
242    ---------
243        plot: bp.figure
244    A Bokeh figure where to render the plot.
245
246        jumpResult: ssscoring.JumpResults
247    A jump results named tuple with score, max speed, scores, data, etc.
248
249        lineColor: str
250    A valid color from the Bokeh palette:  https://docs.bokeh.org/en/2.1.1/docs/reference/colors.html
251    This module defines 8 colors for rendering a competition's results.  See:
252    `ssscoring.notebook.SPEED_COLORS` for the list.
253
254        legend: str
255    A title for the plot.
256
257        showIt: bool
258    A boolean flag for whether the call should render the max speed, time,
259    horizontal speed, etc. in the current plot.  This is used for discriminating
260    between single jump plots and plotting only the speed for the aggregate
261    plot display for a competition or training session.
262
263    To display the actual plot, use `bp.show(plot)` if running from Lucyfer/Jupyter
264    or use `st.bokeh_chart(plot)` if in the Streamlit environment.
265
266    ```python
267    # Basic usage showing speed accuracy overlay
268    graphJumpResult(plot, result)
269    bp.show(plot)
270
271    # Multiple jumps without speed accuracy overlay
272    for result in jumpResults:
273        graphJumpResult(plot, result, showIt=False, showAccuracy=False)
274    bp.show(plot)
275    ```
276    Another alternative use is in Streamlit.io applications:
277
278    ```python
279    # Streamlit app with speed accuracy overlay
280    graphJumpResult(plot, result, showIt=False)
281    st.bokeh_chart(plot, use_container_width=True)
282    ```
283
284    Returns
285    -------
286    `None`.
287    """
288    if jumpResult.data is not None:
289        data = jumpResult.data
290        scores = jumpResult.scores
291        score = jumpResult.score
292        # Main speed line
293        plot.line(data.plotTime, data.vKMh, legend_label = legend, line_width = 2, line_color = lineColor)
294
295        if showIt:
296            maxSpeed = data.vKMh.max()
297            t = data[data.vKMh == maxSpeed].iloc[0].plotTime
298            plot.line(data.plotTime, data.hKMh, legend_label = 'H-speed', line_width = 2, line_color = 'red')
299            _plotSpeedAccuracy(plot, data, jumpResult.window)
300            if scores != None:
301                _graphSegment(plot, scores[score]+3.0, 0.0, scores[score]+3.0, score, 1, 'darkseagreen')
302                _graphSegment(plot, scores[score], 0.0, scores[score], score, 1, 'darkseagreen')
303                plot.scatter(x = [ scores[score]+1.5, ], y = [ score, ], marker = 'circle_cross', size = [ 15, ], line_color = 'limegreen', fill_color = 'darkgreen', line_width = 2)
304                plot.scatter(x = [ t, ], y = [ maxSpeed, ], marker = 'diamond_dot', size = [ 20, ], line_color = 'yellow', fill_color = 'red', line_width = 2)
305
306
307def graphAltitude(plot,
308                  jumpResult,
309                  label = 'Alt (ft)',
310                  lineColor = 'palegoldenrod',
311                  rangeName = 'altitudeFt'):
312    """
313    Graph a vertical axis with additional data, often used for altitude in ft
314    ASL.
315
316    Arguments
317    ---------
318        plot: pb.figure
319    A Bokeh figure where to render the plot.
320
321        jumpResult: ssscoring.JumpResults
322    A jump results named tuple with score, max speed, scores, data, etc.
323
324        label: str
325    The legend label for the new Y axis.
326
327        lineColor: str
328    A color name from the Bokeh palette.
329
330        rangeName: str
331    The range name to associate the `LinearAxis` layout with the data for
332    plotting.
333
334    Returns
335    -------
336    `None`.
337    """
338    data = jumpResult.data
339    plot.line(data.plotTime, data.altitudeAGLFt, legend_label = label, line_width = 2, line_color = lineColor, y_range_name = rangeName)
340
341
342def graphAngle(plot,
343               jumpResult,
344               label = 'angle',
345               lineColor = 'deepskyblue',
346               rangeName = 'angle'):
347    """
348    Graph the flight angle
349
350    Arguments
351    ---------
352        plot: pb.figure
353    A Bokeh figure where to render the plot.
354
355        jumpResult: ssscoring.JumpResults
356    A jump results named tuple with score, max speed, scores, data, etc.
357
358        label: str
359    The legend label for the new Y axis.
360
361        lineColor: str
362    A color name from the Bokeh palette.
363
364        rangeName: str
365    The range name to associate the `LinearAxis` layout with the data for
366    plotting.
367
368    Returns
369    -------
370    `None`.
371    """
372    data = jumpResult.data
373    plot.line(data.plotTime, data.speedAngle, legend_label = label, line_width = 2, line_color = lineColor, y_range_name = rangeName)
374
375
376def graphAcceleration(plot,
377                      jumpResult,
378                      label = 'V-accel m/s²',
379                      lineColor = 'magenta',
380                      rangeName = 'vAccelMS2'):
381    """
382    Graph the flight acceleration curve.
383
384    Arguments
385    ---------
386        plot: pb.figure
387    A Bokeh figure where to render the plot.
388
389        jumpResult: ssscoring.JumpResults
390    A jump results named tuple with score, max speed, scores, data, etc.
391
392        label: str
393    The legend label for the new Y axis.
394
395        lineColor: str
396    A color name from the Bokeh palette.
397
398        rangeName: str
399    The range name to associate the `LinearAxis` layout with the data for
400    plotting.
401
402    Returns
403    -------
404    `None`.
405    """
406    data = jumpResult.data
407    plot.line(data.plotTime, data.vAccelMS2, legend_label = label, line_width = 2, line_color = lineColor, y_range_name = rangeName)
408
409
410
411
412def convertHexColorToRGB(color: str) -> list:
413    """
414    Converts a color in the format `#a0b1c2` to its RGB equivalent as a list
415    of three values 0-255.
416
417    Arguments
418    ---------
419        color
420    A `str` in the form '#xxyyzz` where xx, yy, and zz are values in the hex
421    range 00-FF.  color is case insensitive.
422
423    Returns
424    -------
425    A list of 3 integers, each in the range 0-255 corresponding to the hex
426    color value.
427
428    Raises
429    ------
430    `SSScoringError' if `color` is an invalid hex-encoded textual RGB value.
431    The string value of the exception describes the error cause.
432
433    `ValueError` if the characters that make the hex value are not in the
434    range 0-9, a-f.
435    """
436    if not isinstance(color, str):
437        raise TypeError('Invalid color type - must be str')
438    color = color.replace('#', '')
439    if len(color) != 6:
440        raise SSScoringError('Invalid hex value length')
441    result = [ int(color[x:x+2], 16) for x in range(0, len(color), 2) ]
442    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        'vAccelMS2': bm.Range1d(start = 0.0, end = 15.0),
192        'speedAccuracy': bm.Range1d(start = 0.0, end = speedAccuracyEnd),
193    }
194    plot.add_layout(_initLinearAxis('Alt (ft)', 'altitudeFt', colorName=DEFAULT_AXIS_COLOR_BOKEH), 'left')
195    plot.add_layout(_initLinearAxis('angle', 'angle', colorName=DEFAULT_AXIS_COLOR_BOKEH), 'left')
196    plot.add_layout(_initLinearAxis('Vertical acceleration m/s²', 'vAccelMS2', colorName=DEFAULT_AXIS_COLOR_BOKEH), 'left')
197    plot.add_layout(_initLinearAxis('Speed accuracy ISC', 'speedAccuracy', colorName=DEFAULT_AXIS_COLOR_BOKEH), 'left')
198    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:
201def validationWindowDataFrom(data: pd.DataFrame, window: PerformanceWindow) -> bm.ColumnDataSource:
202    """
203    Generate the validation window dataset for plotting the ISC speed accuracy
204    values.  It's a subset defined from the end of the scoring window to the
205    validation start.
206
207    Arguments
208    ---------
209        data
210    A dataframe with the `plotTime` column set, with all the jump data, after
211    speed validation processing.
212
213        window
214    A `ssscoring.datatypes.PerformanceWindow` instance, with the `validationStart`
215    value initialized.
216
217    Returns
218    -------
219    A column data source ready for plotting the Y-values of a Bokeh chart.
220    """
221    validationData = data[data.altitudeAGL <= window.validationStart]
222    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):
233def graphJumpResult(plot,
234                    jumpResult,
235                    lineColor = 'green',
236                    legend = 'speed',
237                    showIt = True,
238                    showAccuracy = True):
239    """
240    Graph the jump results using the initialized plot.
241
242    Arguments
243    ---------
244        plot: bp.figure
245    A Bokeh figure where to render the plot.
246
247        jumpResult: ssscoring.JumpResults
248    A jump results named tuple with score, max speed, scores, data, etc.
249
250        lineColor: str
251    A valid color from the Bokeh palette:  https://docs.bokeh.org/en/2.1.1/docs/reference/colors.html
252    This module defines 8 colors for rendering a competition's results.  See:
253    `ssscoring.notebook.SPEED_COLORS` for the list.
254
255        legend: str
256    A title for the plot.
257
258        showIt: bool
259    A boolean flag for whether the call should render the max speed, time,
260    horizontal speed, etc. in the current plot.  This is used for discriminating
261    between single jump plots and plotting only the speed for the aggregate
262    plot display for a competition or training session.
263
264    To display the actual plot, use `bp.show(plot)` if running from Lucyfer/Jupyter
265    or use `st.bokeh_chart(plot)` if in the Streamlit environment.
266
267    ```python
268    # Basic usage showing speed accuracy overlay
269    graphJumpResult(plot, result)
270    bp.show(plot)
271
272    # Multiple jumps without speed accuracy overlay
273    for result in jumpResults:
274        graphJumpResult(plot, result, showIt=False, showAccuracy=False)
275    bp.show(plot)
276    ```
277    Another alternative use is in Streamlit.io applications:
278
279    ```python
280    # Streamlit app with speed accuracy overlay
281    graphJumpResult(plot, result, showIt=False)
282    st.bokeh_chart(plot, use_container_width=True)
283    ```
284
285    Returns
286    -------
287    `None`.
288    """
289    if jumpResult.data is not None:
290        data = jumpResult.data
291        scores = jumpResult.scores
292        score = jumpResult.score
293        # Main speed line
294        plot.line(data.plotTime, data.vKMh, legend_label = legend, line_width = 2, line_color = lineColor)
295
296        if showIt:
297            maxSpeed = data.vKMh.max()
298            t = data[data.vKMh == maxSpeed].iloc[0].plotTime
299            plot.line(data.plotTime, data.hKMh, legend_label = 'H-speed', line_width = 2, line_color = 'red')
300            _plotSpeedAccuracy(plot, data, jumpResult.window)
301            if scores != None:
302                _graphSegment(plot, scores[score]+3.0, 0.0, scores[score]+3.0, score, 1, 'darkseagreen')
303                _graphSegment(plot, scores[score], 0.0, scores[score], score, 1, 'darkseagreen')
304                plot.scatter(x = [ scores[score]+1.5, ], y = [ score, ], marker = 'circle_cross', size = [ 15, ], line_color = 'limegreen', fill_color = 'darkgreen', line_width = 2)
305                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'):
308def graphAltitude(plot,
309                  jumpResult,
310                  label = 'Alt (ft)',
311                  lineColor = 'palegoldenrod',
312                  rangeName = 'altitudeFt'):
313    """
314    Graph a vertical axis with additional data, often used for altitude in ft
315    ASL.
316
317    Arguments
318    ---------
319        plot: pb.figure
320    A Bokeh figure where to render the plot.
321
322        jumpResult: ssscoring.JumpResults
323    A jump results named tuple with score, max speed, scores, data, etc.
324
325        label: str
326    The legend label for the new Y axis.
327
328        lineColor: str
329    A color name from the Bokeh palette.
330
331        rangeName: str
332    The range name to associate the `LinearAxis` layout with the data for
333    plotting.
334
335    Returns
336    -------
337    `None`.
338    """
339    data = jumpResult.data
340    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'):
343def graphAngle(plot,
344               jumpResult,
345               label = 'angle',
346               lineColor = 'deepskyblue',
347               rangeName = 'angle'):
348    """
349    Graph the flight angle
350
351    Arguments
352    ---------
353        plot: pb.figure
354    A Bokeh figure where to render the plot.
355
356        jumpResult: ssscoring.JumpResults
357    A jump results named tuple with score, max speed, scores, data, etc.
358
359        label: str
360    The legend label for the new Y axis.
361
362        lineColor: str
363    A color name from the Bokeh palette.
364
365        rangeName: str
366    The range name to associate the `LinearAxis` layout with the data for
367    plotting.
368
369    Returns
370    -------
371    `None`.
372    """
373    data = jumpResult.data
374    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 graphAcceleration( plot, jumpResult, label='V-accel m/s²', lineColor='magenta', rangeName='vAccelMS2'):
377def graphAcceleration(plot,
378                      jumpResult,
379                      label = 'V-accel m/s²',
380                      lineColor = 'magenta',
381                      rangeName = 'vAccelMS2'):
382    """
383    Graph the flight acceleration curve.
384
385    Arguments
386    ---------
387        plot: pb.figure
388    A Bokeh figure where to render the plot.
389
390        jumpResult: ssscoring.JumpResults
391    A jump results named tuple with score, max speed, scores, data, etc.
392
393        label: str
394    The legend label for the new Y axis.
395
396        lineColor: str
397    A color name from the Bokeh palette.
398
399        rangeName: str
400    The range name to associate the `LinearAxis` layout with the data for
401    plotting.
402
403    Returns
404    -------
405    `None`.
406    """
407    data = jumpResult.data
408    plot.line(data.plotTime, data.vAccelMS2, legend_label = label, line_width = 2, line_color = lineColor, y_range_name = rangeName)

Graph the flight acceleration curve.

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:
413def convertHexColorToRGB(color: str) -> list:
414    """
415    Converts a color in the format `#a0b1c2` to its RGB equivalent as a list
416    of three values 0-255.
417
418    Arguments
419    ---------
420        color
421    A `str` in the form '#xxyyzz` where xx, yy, and zz are values in the hex
422    range 00-FF.  color is case insensitive.
423
424    Returns
425    -------
426    A list of 3 integers, each in the range 0-255 corresponding to the hex
427    color value.
428
429    Raises
430    ------
431    `SSScoringError' if `color` is an invalid hex-encoded textual RGB value.
432    The string value of the exception describes the error cause.
433
434    `ValueError` if the characters that make the hex value are not in the
435    range 0-9, a-f.
436    """
437    if not isinstance(color, str):
438        raise TypeError('Invalid color type - must be str')
439    color = color.replace('#', '')
440    if len(color) != 6:
441        raise SSScoringError('Invalid hex value length')
442    result = [ int(color[x:x+2], 16) for x in range(0, len(color), 2) ]
443    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.