Black Lives Matter. Please consider donating to Black Girls Code today.

Can't get a gauge like pie chart to rotate clockwise

I was trying to create a gauge to indicate percentage change. The onlly example I can find is this gauge here:Screenshot%20from%202018-10-30%2018-10-15
but I can’t get the needle to rotate. So instead, I use the color to indicate changes. Here is my mock up code:

from ipywidgets import FloatLogSlider, interact
@interact(ratio=FloatSlider(min=0, max=50, step=1, value=10))
def show_improve(ratio):
    color_pair = ['rgb(232,206,202)','rgb(226,126,64)']
    #if ratio>24:
    #    color_pair = color_pair[::-1]
    base_chart = {
        "values": [40, 10, 10, 10, 10, 10, 10],
        "labels": ["-", "10", "8%", "6%", "4%", "2%", "0"],
        "domain": {"x": [0, .48]},
        "marker": {
            "colors": [
                'rgb(255, 255, 255)',
                'rgb(255, 255, 255)',
                'rgb(255, 255, 255)',
                'rgb(255, 255, 255)',
                'rgb(255, 255, 255)',
                'rgb(255, 255, 255)',
                'rgb(255, 255, 255)'
            ],
            "line": {
                "width": 1
            }
        },
        "name": "Gauge",
        "hole": .4,
        "type": "pie",
        "direction": "clockwise",
        "rotation": 108,
        "showlegend": False,
        "hoverinfo": "none",
        "textinfo": "label",
        "textposition": "outside"
    }

    meter_chart = {
        "values": [50, ratio, 0],
        "marker": {
            'colors': ['rgb(255, 255, 255)', *(color_pair[::-1])]
        },
        "domain": {"x": [0, 0.48]},
        "name": "Gauge",
        "hole": .3,
        "type": "pie",
        "direction": "counterclockwise",
        "rotation": 90,
        "showlegend": False,
        "textinfo": "label",
        "textposition": "none",
        #"hoverinfo": "none"
    }

    layout = {
        'xaxis': {
            'showticklabels': False,
            'showgrid': False,
            'zeroline': False,
        },
        'yaxis': {
            'showticklabels': False,
            'showgrid': False,
            'zeroline': False,
        },
        'annotations': [
            {
                'xref': 'paper',
                'yref': 'paper',
                'x': 0.23,
                'y': 0.45,
                'text': '{:.0%}'.format(ratio/50*0.1),
                'showarrow': False
            }
        ]
    }

    # we don't want the boundary now
    base_chart['marker']['line']['width'] = 0

    gauge_fig = {"data": [base_chart, meter_chart],
                 "layout": layout}
    iplot(gauge_fig)

Screenshot%20from%202018-10-31%2010-15-55
But I can’t get it to work for counter clockwise rotation. The main problem is when I switch the rotation to clock wise, the color is not the deep orange, but instead just white.

Any suggestion as to how I can do this?

Hi @chainster_mike,

You might want to look at using the new barpolar trace type (https://plot.ly/python/wind-rose-charts/). This would let you work directly in angular coordinates, which might be more natural in this case.

Here’s how you could draw the initial gauge

import plotly.graph_objs as go
fig = go.FigureWidget()
fig.add_barpolar(r = [1, 1, 1, 1, 1],
                 theta = [0, 36, 72, 108, 144],
                 offset=0,
                 width=36,
                 marker={'color': [0, 1, 2, 3, 4]})

# Configure polar 1
fig.layout.polar.hole = 0.4
fig.layout.polar.angularaxis.showgrid = False
fig.layout.polar.radialaxis.showgrid = False
fig.layout.polar.radialaxis.range = [0, 1]
fig.layout.polar.radialaxis.tickvals = []
fig.layout.polar.bargap = 0.9
fig.layout.polar.sector = [0, 180]
fig.layout.polar.domain.x = [0, 1]
fig

Then you could even use a second smaller polar line plot as the needle

needle = fig.add_scatterpolar(r=[1, 0, 0, 1],
                              theta=[0, -20, 20, 0],
                              fill='tonext',
                              mode='lines',
                              subplot = 'polar2')
# Configure polar 2 for needle
fig.layout.polar2 = {}
fig.layout.polar2.hole = 0.1
fig.layout.polar2.angularaxis.showgrid = False
fig.layout.polar2.radialaxis.showgrid = False
fig.layout.polar2.radialaxis.range = [0, 1]
fig.layout.polar2.radialaxis.tickvals = []
fig.layout.polar2.bargap = 0.9
fig.layout.polar2.sector = [0, 180]
fig.layout.polar2.domain.x = [0, 1]
fig.layout.polar2.domain.y = [0, 0.35]
fig.layout.polar2.angularaxis.tickvals = []
fig.layout.polar2.radialaxis.tickvals = []
fig.layout.polar2.angularaxis.showline = False
fig.layout.polar2.radialaxis.showline = False
fig

Then you could set the needle’s angle with the fig.layout.polar2.angularaxis.rotation property

# Set needle angle
fig.layout.polar2.angularaxis.rotation = 120
fig

Hope that gives you some ideas!
-Jon

1 Like

Thank you very much! I learn a lot from your reply!

1 Like