Search code examples
pythonmatplotlibplotlyradar-chart

Python Plotly Radar Chart with Style


I'm trying to the image shown below and I thought python would be a good idea to do this but I'm not sure. I want to randomize lots of football players' stats, make a radar chart for each and save the charts as images. enter image description here

But the plotly radar charts are not so stylish and I really want to make something stylish. How to turn the below demo code into the reference image and is it possible?

Here's a demo code:

import plotly.graph_objects as go

categories = ['Defending','Speed','Attacking',
              'Technical', 'Team play']

fig = go.Figure()

fig.add_trace(go.Scatterpolar(
      r=[1, 5, 2, 2, 3],
      theta=categories,
      fill='toself',
      name='Alice'
))
fig.add_trace(go.Scatterpolar(
      r=[4, 3, 2.5, 1, 2],
      theta=categories,
      fill='toself',
      name='Bob'
))

fig.update_layout(
  polar=dict(
    radialaxis=dict(
      visible=True,
      range=[0, 5]
    )),
  showlegend=False
)

fig.show()

Solution

  • From the documentation for polar layout, it seems that Plotly does not offer much options when it comes the grid shape itself. However, Plotly allows you to create your own templates/themes or examine built-in themes.

    As a starting point, you should probably analyze the plotly_dark theme as it has some features similar to your picture.

    simple example with built-in template

    enter image description here

    dataset.csv
    categories,player,points
    Defending,alice,1
    Speed,alice,5
    Attacking,alice,2
    Technical,alice,2
    Team play,alice,3
    Defending,bob,4
    Speed,bob,3
    Attacking,bob,2.5
    Technical,bob,1
    Team play,bob,2
    
    code
    import plotly.express as px
    import pandas as pd
    
    df = pd.read_csv("dataset.csv")
    fig = px.line_polar(df, r="points",
                        theta="categories",
                        color="player",
                        line_close=True,
                        color_discrete_sequence=["#00eb93", "#4ed2ff"],
                        template="plotly_dark")
    
    fig.update_polars(angularaxis_showgrid=False,
                      radialaxis_gridwidth=0,
                      gridshape='linear',
                      bgcolor="#494b5a",
                      radialaxis_showticklabels=False
                      )
    
    fig.update_layout(paper_bgcolor="#2c2f36")
    fig.show()
    

    With the above code I don't think it is possible to modify the color of each nested shape. To be able to do so, you will probably have to create your own template and color each nested shape separately.

    creating grid shape

    You might have to try something similar the code below to create your desired grid shape.

    import plotly.graph_objects as go
    
    bgcolors = ["#353841", "#3f414d", "#494b5a", "#494b5a", "#58596a"]
    fig = go.Figure(go.Scatterpolar(
        r=[42]*8,
        theta=[0, 45, 90, 135, 180, 225, 270, 315],
        marker_line_width=2,
        opacity=0.8,
        marker=dict(color=bgcolors[0])
    ))
    
    for i in range(1, 5):
        fig.add_trace(go.Scatterpolar(
            r=[44-6*i]*8,
            theta=[0, 45, 90, 135, 180, 225, 270, 315],
            marker_line_width=2,
            marker=dict(color=bgcolors[i])
        ))
    
    fig.update_polars(angularaxis_dtick='')
    fig.update_traces(fill='toself')
    fig.update_polars(angularaxis_showgrid=False,
                      radialaxis_showgrid=False,
                      radialaxis_gridwidth=0,
                      gridshape='linear',
                      radialaxis_showticklabels=False,
                      angularaxis_layer='above traces'
    
                      )
    fig.show()
    
    

    enter image description here

    The colors are off but the general shape is good.