I am trying to implement a dashboard with Streamlit where to show real-time data. This data is collected from a sensor and then plotted into the dashboard using the Plotly Express library. The main idea I have been using to do this is creating a loop executed during X seconds. Inside, we find the following:
- We call the update_position function, that calls the sensor, receives the data and returns position and epoch time
- We call the print_plot function, that takes the position as an argument and prints the value
This was working, but the latency was really high, thus not making it intuitive. I thought of using a parallel approach in which points 1 and 2 are run at the same time (I donβt care if they are not synchronised, as we are plotting always the latest position updated)
I have implemented this into Python using multiprocess.Process as it follows, but now the plot is not appearing in the screen. This is my code
def update_position(information, players, positions, qout):
for player in players:
# Get the service for each provider
yvalue, provider_name, epoch = get_values(f'pressure{player.n}')
# Update the data for each player
if provider_name == player.provider_name:
player.update(yvalue)
positions.append(player.y)
positions = positions[-information['Voters']:]
qout.put([epoch, positions])
def print_plot(information, positions, fig):
# Update the plot
fig.update_traces(x=information['Providers'], y=positions, marker_size=20, hovertemplate=None, hoverinfo='skip')
fig.update_layout({'plot_bgcolor': 'rgba(0, 0, 0, 0)', 'paper_bgcolor': 'rgba(0, 0, 0, 0)'})
box7.plotly_chart(fig, config={"displayModeBar": False, "showTips": False, 'scrollZoom': False})
# Question to load the voting screen
def question_vote(i, information, players):
positions = []
# To fill the array with zeros
for n in range(information['Voters']):
positions.append(0)
# Check which kind of question do we have
if information['Answers'][i] == 0:
yaxes = "No Yes"
else:
yaxes = "Disagree Agree"
box1.markdown(f"<h1 style='text-align: center; color: black;font-size: 250%'>{information['Questions'][i]}</h1>", unsafe_allow_html=True)
# Print the plot
fig = px.scatter(x=information['Providers'], y=positions)
fig.update_yaxes(range=[0, 100], title_text=yaxes)
fig.update_xaxes(type='category', title_text="")
orig_time = int(time.time())
epoch = orig_time + 1
qout = mp.Queue()
# Execute the loop during the seconds assigned for each question
while (epoch - orig_time) < information['Times'][i]:
print('Hola')
p1 = mp.Process(target=update_position, args=(information, players, positions, qout))
p2 = mp.Process(target=print_plot, args=(information, positions, fig))
p1.start()
p2.start()
p1.join()
p2.join()
out = qout.get()
epoch = out[0]
positions = out[1]
# Save the last positions into the results dictionary
save_results(players, information, i)
# Reset all the positions
for player in players:
player.reset()
box1.empty()
box2.empty()
box3.empty()
box4.empty()
box5.empty()
box6.empty()
box7.empty()
box8.empty()
box9.empty()
box10.empty()
box11.empty()
box12.empty()
Do you have any idea how I can speed up the visualisation? Multiprocess seems to be slow