I love data visualization and, even more than that, I love plotting data I do care about. One of the data set I was playing with recently came from the Marmotte Granfondo Alpes 2017. In a nutshell, I’m plotting the finish time distribution alongside the weighted power and weighted power per kilo. In addition to that I’m coloring the markers according to the medal earned, namely gold, silver or bronze.

Up till now I was doing all visualization using the matplotlib resulting in static charts. What I would like to do, however, is to move towards more interactive vis in an effort to show more aspects of bike racing, namely average speed, max power, threshold power, stress score, etc. without cluttering the graph. Ideally it would be a switch to toggle different information.

Welcome Plot.ly

One of the popular trend in the modern python ecosystem is to leverage all great work done by the javascript community on the web front-end. The loud example of such work is a plotting library Plotly.

On a surface it looks like any other declarative plotting library, but behind the hood it generates d3.js powered script, ready to be consumed by any HTML document, including Jupyter notebook and Jekyll Github blog.

Example of the scripted plot is shown below. I went all-in, when it comes to minimizing the inc, and removed all labels. The context of the information can be uncovered by hovering over the markers.

Pain in the neck

Few remarks on the challenges I’ve faced.

Plot.ly easily recognized python datetime objects, but struggles with python timedelta objects. I needed to show the time on my plot in the ‘%HH:%MM:%SS’ format, namely no date part, and solved this issue by:

Converting my timedelta objects to datetime objects:

df['official time'] = pd.to_datetime(pd.to_timedelta(df['official time'], unit='s'))

Specifying on the Plotly Layout object the display tickformat for xaxis:

Layout(
  xaxis=dict(
      tickformat='%X',
    )
  )

Another issue I’ve encountered and failed to solve was the zero-line on the upper subplot. I wanted to get rid of it altogether, but none of the found tricks did help.

The snippet below should remove the line in theory, but does not in practice:

Layout(
  xaxis=dict(
    zeroline=False,
    showline=False,
    )
  )