how to implement two thresholds in Plotly gauge chart - Python - python

I'm using Plotly gauge charts in my Django project. I need to show two thresholds for the upper and lower boundary of some parameter which is being projected in the chart.
here is my chart in views.py:
gauge_do = go.Figure(go.Indicator(
mode = "gauge+number",
value = 1.7,
domain = {'x': [0, 1], 'y': [0, 1]},
title = {'text': "Oxygen [mg/L]"},
gauge = {'axis': {'range': [0, 10]},
'bar': {'color': "salmon"},
'threshold' : {'line': {'color': "red", 'width': 4}, 'thickness': 0.75, 'value': 2}
}
)
)
gauge_do.update_layout(font = {'color': "black", 'family': "Arial"}, margin = dict(t=0, b=0, l=5, r=5,), height=230)
div_do = opy.plot(gauge_do, auto_open=False, config=config, output_type='div')
Here, there is one threshold with value of 'value': 2.
In my case, I want to show the minimum acceptable value and maximum acceptable value by two indicators ( exactly as threshold ), say min=2 and max=8.
the plotly doesnt accept using two 'threshold's.
any ideas?

From the documentation, it seems like they intend steps to do this. Something like:
gauge_do = go.Figure(
go.Indicator(
mode = "gauge+number",
value = 1.7,
domain = {'x': [0, 1], 'y': [0, 1]},
title = {'text': "Oxygen [mg/L]"},
gauge = {'axis': {'range': [0, 10]},
'bar': {'color': "salmon"},
'steps' : [{
'color': 'white',
'line': {'color': "red", 'width': 4},
'thickness': 0.75,
'range': [2,8]}]
}
)
)

Related

The color is not showing in choropleth mapbox

The Map is showing but the colors are not being shown in the output.
There is something wrong in the code which I'm not being able to find.
#app.callback(
Output('my_graph', 'figure'),
Input('my_dd', 'value')
)
def update_graph(selected):
dff = df_map[df_map['listed_in'] == selected]
dff1 = dff.groupby(['listed_in', 'country']).size().reset_index(name='count')
print(dff1.head())
fig = px.choropleth_mapbox(dff1,
geojson=Countries,
locations=dff1.country,
color='count',
mapbox_style='carto-positron',
zoom=1,
center={'lat': 19, 'lon': 11},
opacity=0.2)
fig.update_layout(
margin={'r': 0, 't': 0, 'l': 0, 'b': 0},
mapbox=dict(accesstoken=mapbox_access_token)
)`enter code here`
return fig
Here is the output

Plotly dashboard completely restarts

I have a plotly dashboard built with dash. Some of the chart elements are set to refresh every couple of seconds. Instead of just refreshing that individual dashboard, the entire webpage refreshes and it rebuilds every element.
This is an example of how the code is written that updates the charts-
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div(
html.Div([
dcc.Graph(id='live-update-graph'),
dcc.Interval(
id='interval-component',
interval=1*1000, # in milliseconds
n_intervals=0
)
])
)
#app.callback(Output('live-update-graph', 'figure'),
Input('interval-component', 'n_intervals'))
def update_graph_live(n):
satellite = Orbital('TERRA')
data = {
'time': [],
'Latitude': [],
'Longitude': [],
'Altitude': []
}
# Collect some data
for i in range(180):
time = datetime.datetime.now() - datetime.timedelta(seconds=i*20)
lon, lat, alt = satellite.get_lonlatalt(
time
)
data['Longitude'].append(lon)
data['Latitude'].append(lat)
data['Altitude'].append(alt)
data['time'].append(time)
# Create the graph with subplots
fig = plotly.tools.make_subplots(rows=2, cols=1, vertical_spacing=0.2)
fig['layout']['margin'] = {
'l': 30, 'r': 10, 'b': 30, 't': 10
}
fig['layout']['legend'] = {'x': 0, 'y': 1, 'xanchor': 'left'}
fig.append_trace({
'x': data['time'],
'y': data['Altitude'],
'name': 'Altitude',
'mode': 'lines+markers',
'type': 'scatter'
}, 1, 1)
return fig
My desired outcome is that just the plot element refreshes but not the entire webpage.

Display multi bullet charts in two seperate rows in dash/plotly python

I would like to display multi bullet charts and icons using dash and plotly in separate rows. I would like them to display something like the image below. I've already implemented the multi bullet chart on one row. I'm having trouble placing another multi bullet chart beside this one with icons because of the domain x and y positioning. Here's the code that I have so far. Once I get this I would be adding a drop down to display this information.
app = dash.Dash(__name__)
fig = go.Figure()
fig.add_trace(go.Indicator(
mode = "number+gauge+delta", value = 180,
delta = {'reference': 200},
domain = {'x': [0.25, 1], 'y': [0.08, 0.25]},
title = {'text': "SV 3"},
gauge = {'shape': "bullet"}))
fig.add_trace(go.Indicator(
mode = "number+gauge+delta", value = 35,
delta = {'reference': 200},
domain = {'x': [0.25, 1], 'y': [0.4, 0.6]},
title = {'text': "SV 2"},
gauge = {'shape': "bullet"}))
fig.add_trace(go.Indicator(
mode = "number+gauge+delta", value = 220,
delta = {'reference': 200},
domain = {'x': [0.25, 1], 'y': [0.7, 0.9]},
title = {'text' :"SV 1"},
gauge= {'shape': "bullet"}))
fig.update_layout(height = 400 , margin = {'t':0, 'b':0, 'l':0})
fig.show()
app.run_server(debug=True, use_reloader=True)
I would recommend you to work with dash-bootstrap-components!
layout = html.Div(
[
dbc.Row(
dbc.Col
(html.Div("A single, half-width column"), width=6)),
dbc.Row(
[
dbc.Col(fig, width=3),
dbc.Col(html.Div("Some space in the middle")),
dbc.Col(html.Div("One of your other elements"), width=3),
]
),
]
)

Drag and move the vertical line on the time series data graph to mark and hold

I want to use Python plotly to mark a vertical line that can be dragged around on a time series data graph.
Share my image below.
I remember browsing the plotly or dash web pages that previously described the features of this image, but I couldn't find it when I searched again.
If my mistake is, please let me know how to realize this function.
One approach is to use a shapes object in a dcc.Graph. You have to configure the graph to editable to be able to move the shape. You can then use the relayoutData property of the dcc.Graph as input in the callback function in order to get the position of the shape on the graph. This is explained in the link below. I don't think there is a way to restrict the movement of the shape, unfortunately. So in your case, there is no way to restrict the vertical line to stay vertical. A user would be able to alter it's angle, for example.
https://community.plotly.com/t/moving-the-location-of-a-graph-point-interactively/7161/2
I've also included some starter code as an example of a movable vertical line on a dash plot.
import json
from textwrap import dedent as d
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
app = dash.Dash(__name__)
app.css.append_css({'external_url': 'https://codepen.io/chriddyp/pen/dZVMbK.css'})
styles = {'pre': {'border': 'thin lightgrey solid', 'overflowX': 'scroll'}}
app.layout = html.Div(className='row', children=[
dcc.Graph(
id='basic-interactions',
className='six columns',
figure={
'data': [{
'x': [1, 2, 3, 4],
'y': [4, 1, 3, 5],
'text': ['a', 'b', 'c', 'd'],
'customdata': ['c.a', 'c.b', 'c.c', 'c.d'],
'name': 'Trace 1',
'mode': 'markers',
'marker': {
'size': 12
}
}, {
'x': [1, 2, 3, 4],
'y': [9, 4, 1, 4],
'text': ['w', 'x', 'y', 'z'],
'customdata': ['c.w', 'c.x', 'c.y', 'c.z'],
'name': 'Trace 2',
'mode': 'markers',
'marker': {
'size': 12
}
}],
'layout': {
'shapes': [{
'type': 'line',
'x0': 0.5,
'x1': 0.5,
'xref': 'paper',
'y0': 0,
'y1': 9,
'yref': 'y',
'line': {
'width': 4,
'color': 'rgb(30, 30, 30)',
'dash': 'dashdot'
}
}]
}
},
config={
'editable': True,
'edits': {
'shapePosition': True
}
}
),
html.Div(
className='six columns',
children=[
html.Div(
[
dcc.Markdown(
d("""
**Zoom and Relayout Data**
""")),
html.Pre(id='relayout-data', style=styles['pre']),
]
)
]
)
])
#app.callback(
Output('relayout-data', 'children'),
[Input('basic-interactions', 'relayoutData')])
def display_selected_data(relayoutData):
print("relayoutData:" + str(relayoutData))
return json.dumps(relayoutData, indent=2)
if __name__ == '__main__':
app.run_server(debug=True)

Iterate on figures in plotly to create an animation

My function to create figures looks as follows:
def bar_plot_plotly(self, frame=None):
md = self.get_book()
plotly.offline.init_notebook_mode(connected=True)
fig = go.Figure()
if md:
for step in range(2):
fig.add_trace(go.Indicator(
mode = "number+gauge+delta", value = md.qasks[step],
delta = {'reference': md.qasks[step]},
domain = {'x': [0, 0.4], 'y': [0.2*step, 0.2*step+0.1]},
title = {'text': str(md.asks[step])},
gauge = {
'shape': "bullet",
'axis': {'range': [min(md.qasks), max(md.qasks)]},
'threshold': {
'line': {'color': "red", 'width': 2},
'thickness': 0.75,
'value': md.qasks[step]},
'bar': {'color': "red"}}))
fig.add_trace(go.Indicator(
mode = "number+gauge+delta", value = md.qbids[step],
delta = {'reference': md.qbids[step]},
domain = {'x': [0.6, 1], 'y': [0.2*step, 0.2*step+0.1]},
title = {'text': str(md.bids[step])},
gauge = {
'shape': "bullet",
'axis': {'range': [min(md.qbids), max(md.qbids)]},
'threshold': {
'line': {'color': "green", 'width': 2},
'thickness': 0.75,
'value': md.qbids[step]},
'bar': {'color': "green"}}))
So at each iteration, it creates a figure, my goal would be to iterate on each of those figures in order to create an animation. The idea would be to do the same as in the documentation https://plot.ly/python/animations/#animated-bar-charts-with-plotly-express, but in there they use a pandas DataFrame, I would like to do it per figure basically.
I used to use Funcanimation on matplotlib, I was thus wondering if it was possible to use the above code to do the same? Any advice is more than welcome!
Thanks

Categories