Search code examples
pythonpython-3.xplotlyplotly-dashplotly-python

Is it possible to generate a clock chart using Plotly?


I'm developing a dataviz project and I came across the report generated by Last.FM, in which there is a clock chart to represent the distribution of records by hours.

The chart in question is this:

this

It is an interactive graph, so I tried to use the Plotly library to try to replicate the chart, but without success.

Is there any way to replicate this in Plotly? Here are the data I need to represent

listeningHour  = df.hour.value_counts().rename_axis('hour').reset_index(name='counts')
listeningHour
   hour counts
0   17  16874
1   18  16703
2   16  14741
3   19  14525
4   23  14440
5   22  13455
6   20  13119
7   21  12766
8   14  11605
9   13  11575
10  15  11491
11  0   10220
12  12  7793
13  1   6057
14  9   3774
15  11  3476
16  10  1674
17  8   1626
18  2   1519
19  3   588
20  6   500
21  7   163
22  4   157
23  5   26

Solution

  • The graph provided by Plotly is a polar bar chart. I have written a code using it with your data. At the time of my research, there does not seem to be a way to place the ticks inside the doughnut. The point of the code is to start at 0:00 in the direction of the angle axis. The clock display is a list of 24 tick places with an empty string and a string every 6 hours. The angle grid is aligned with the center of the bar chart.

    import plotly.graph_objects as go
    
    r = df['counts'].tolist()
    theta = np.arange(7.5,368,15)
    width = [15]*24
    
    ticktexts = [f'$\large{i}$' if i % 6 == 0 else '' for i in np.arange(24)]
    
    fig = go.Figure(go.Barpolar(
        r=r,
        theta=theta,
        width=width,
        marker_color=df['counts'],
        marker_colorscale='Blues',
        marker_line_color="white",
        marker_line_width=2,
        opacity=0.8
    ))
    
    fig.update_layout(
        template=None,
        polar=dict(
            hole=0.4,
            bgcolor='rgb(223, 223,223)',
            radialaxis=dict(
                showticklabels=False,
                ticks='',
                linewidth=2,
                linecolor='white',
                showgrid=False,
            ),
            angularaxis=dict(
                tickvals=np.arange(0,360,15),
                ticktext=ticktexts,
                showline=True,
                direction='clockwise',
                period=24,
                linecolor='white',
                gridcolor='white',
                showticklabels=True,
                ticks=''
            )
        )
    )
    
    fig.show()
    

    enter image description here