I have a dashboard with several tabs and charts/tables. The tab that renders on initial page load has an array of five gauge charts (pie charts cut in half with a hole and a line drawn for an indicator) at the top. It looks like this:
Occasionally, one of the charts will not render, like this:
Here is the error I get in the console:

Upgrading to Dash 1.2 seems to have fixed the issue if I run the application locally, but when run from the server, the problem still persists. Sometimes it fails every page load, and sometimes there can be 30+ page loads before a chart doesn’t render, and it’s not always the same chart.
The code for the entire app is very long, but here’s where the gauges are in the layout (the link tags are so the charts can be clickable to be used as filters for a bar chart below):
html.Div(
id='top',
children=[
html.Div(
id='gauge_div',
children=[
html.Div(
id='gauge_title'
)] + [
html.A(
id=f'link{i+1}',
className='gauge_link',
children=dcc.Graph(
id=f'gauge{i+1}',
config={
"displaylogo": False,
'modeBarButtonsToRemove': [
i for i in modeBar_opts if i not
in ['toImage']]
}
)
) for i in range(len(rating_titles))
]
)
]
)
Callback:
@app.callback(
[Output(f'gauge{i+1}', 'figure') for i in range(len(rating_titles))] +
[Output(f'link{i+1}', 'style') for i in range(len(rating_titles))],
[Input('dash_data', 'children'),
Input('selected', 'value')]
)
def update_gauge(df, selected):
'''When gauge chart selected or filtered data updated, remake gauge
charts with special styling for selected gauge; if no data, hide all'''
if df and len(pd.DataFrame(json.loads(df))) > 0:
dff = pd.DataFrame(json.loads(df))
dff.loc[:, 'startdate'] = dff.apply(
lambda x: datetime.fromtimestamp(x['startdate']/1000), axis=1)
dff['startdate'] = dff['startdate'].dt.date
gauges = []
for i in range(1, len(rating_titles) + 1):
if i:
if selected == str(i) or selected == i:
color = '#777373'
weight = ['<b>', '</b>']
else:
color = 'rgba(255,0,0,0)'
weight = ['', '']
else:
color = 'rgba(255,0,0,0)'
weight = ['', '']
gauges.append(
gauge_chart(
dff, rating_titles, f'{rating_array}[{i}]', color=color,
weight=weight))
return gauges + [
{'visibility': 'visible'} for _ in range(len(rating_titles))]
else:
fig = {'data': go.Bar(), 'layout': go.Layout()}
return [fig for _ in range(len(rating_titles))] + [
{'visibility': 'hidden'} for _ in range(len(rating_titles))]
Here’s the gauge_chart() function that’s called in the callback:
def gauge_chart(df, rating_titles, col, color='rgba(255,0,0,0)',
weight=['', '']):
if weight == ['', '']:
opac = 0.6
indic = '#00000099'
else:
opac = 1
indic = 'black'
RatingOutOf = 5
divisions = RatingOutOf - 1
AverageRating = df[col].mean()
Angle = 180 - (((AverageRating - 1) / (RatingOutOf - 1)) * 180)
colors = ['rgba(255,0,0,0)'] + [
c.get_hex() for c in Color('green').range_to('red', divisions)
]
vals = [50] + [(50/divisions)]*divisions
catNum = int(col.split('[')[1][:-1])
Title = '<br>'.join(textwrap.wrap(
rating_titles[catNum - 1], width=30))
Origin = (0.5, 0.5)
Length = .4
EndX = Origin[0] + (math.cos(math.radians(Angle)) * Length)
EndY = Origin[1] + math.sqrt(abs(Length**2 - (abs(EndX - Origin[0]))**2))
gauge = {
'values': vals,
'opacity': opac,
'textposition': 'none',
'rotation': 90,
'sort': False,
'domain': {'x': [0, 1], 'y': [-1, 1]},
'xref': 'paper',
'yref': 'paper',
'hole': .6,
'type': 'pie',
'marker': {
'colors': colors,
'line': {'color': 'rgba(255,0,0,0)', 'width': 0}
},
'showlegend': False,
'hoverinfo': 'none'
}
layout = {
'title': f'{weight[0]}{Title}{weight[1]}',
'width': 350,
'height': 350,
'modebar': {
'bgcolor': 'rgba(0,0,0,0)',
'color': '#2262AF',
'activecolor': '#85AD40'
},
'plot_bgcolor': 'rgba(255,0,0,0)',
'paper_bgcolor': 'rgba(255,0,0,0)',
'margin': go.layout.Margin(
l=10,
r=10,
b=10,
t=50
),
'annotations': [
{
'font': {'size': 24},
'showarrow': False,
'text': f'{weight[0]}{round(AverageRating, 1)}{weight[1]}',
'x': Origin[0],
'y': Origin[1] + 0.02,
'xref': 'paper',
'yref': 'paper'
},
{
'font': {'size': 12},
'showarrow': False,
'text': '',
'x': Origin[0],
'y': Origin[1],
'xref': 'paper',
'yref': 'paper'
}
],
'shapes': [
{
'type': 'rect',
'fillcolor': 'white',
'x0': 0,
'y0': Origin[1] - 0.15,
'x1': 1,
'y1': 1.2,
'line': {'width': 0, 'color': 'rgba(255,0,0,0)'},
'xref': 'paper',
'yref': 'paper',
'layer': 'below'
},
{
'type': 'line',
'x0': Origin[0],
'y0': Origin[1],
'x1': EndX,
'y1': EndY,
'line': {'width': 7, 'color': indic},
'xref': 'paper',
'yref': 'paper'
},
{
'type': 'circle',
'fillcolor': 'white',
'x0': Origin[0] - 0.15,
'y0': Origin[1] - 0.15,
'x1': Origin[0] + 0.15,
'y1': Origin[1] + 0.15,
'line': {'width': 0},
'xref': 'paper',
'yref': 'paper'
}
]
}
fig = {'data': [gauge], 'layout': layout}
return fig