Summary
Trying to plot my brain waves in streamlit but got an issue where it creates many plot appending on the page:
Steps to reproduce
Code snippet:
code: brainwaves.py · GitHub
Expected behavior:
just a single chart where traces are added
Trying to plot my brain waves in streamlit but got an issue where it creates many plot appending on the page:
Code snippet:
code: brainwaves.py · GitHub
Expected behavior:
just a single chart where traces are added
The basic way to do it is to create an empty placeholder container, and always reuse that container. Here’s a very simplified version of your app:
@blackary thanks that’s perfect!
It solved my problem but i’m facing the issue again when using two “with” with columns:

import json
import asyncio
import numpy as np
import streamlit as st
import plotly.graph_objects as go
import pandas as pd
from sklearn.decomposition import IncrementalPCA
from websockets import connect
waves = {
"delta": [0.1, 4],
"theta": [4, 7.5],
"alpha": [7.5, 12.5],
"beta": [12.5, 30],
"gamma": [30, 100]
}
figs = {}
pcas = {}
data = {
"delta": [],
"theta": [],
"alpha": [],
"beta": [],
"gamma": []
}
empty = {
"delta": st.empty(),
"theta": st.empty(),
"alpha": st.empty(),
"beta": st.empty(),
"gamma": st.empty()
}
for name, band in waves.items():
figs[name] = go.Figure()
pcas[name] = IncrementalPCA(n_components=3)
batch_size = 10
async def print_messages():
global data
async with connect("ws://localhost:8080") as ws:
while True:
msg = await ws.recv()
# Extract theta
new_data = json.loads(msg)['data']
for name in waves:
data[name].append(new_data[name])
if len(data["alpha"]) >= batch_size:
for name in waves:
# Extract theta
X = np.array(data[name])
# Reshape
X = X.reshape(len(data[name]), -1)
# Update PCA
pcas[name].partial_fit(X)
data[name] = []
# Create dataframe
df = pd.DataFrame(pcas[name].transform(X),
columns=['PC1', 'PC2', 'PC3'])
# Update figure
figs[name].add_trace(go.Scatter3d(
x=df['PC1'], y=df['PC2'], z=df['PC3'],
mode='markers')
)
col1, col2 = st.columns(2)
with empty["delta"].container(), col1:
st.header("Delta")
st.plotly_chart(figs["delta"], use_container_width=True)
with empty["theta"].container(), col2:
st.header("Theta")
st.plotly_chart(figs["theta"], use_container_width=True)
col3, col4 = st.columns(2)
with empty["alpha"].container(), col3:
st.header("Alpha")
st.plotly_chart(figs["alpha"], use_container_width=True)
with empty["beta"].container(), col4:
st.header("Beta")
st.plotly_chart(figs["beta"], use_container_width=True)
col5, _ = st.columns(2)
with empty["gamma"].container(), col5:
st.header("Gamma")
st.plotly_chart(figs["gamma"], use_container_width=True)
asyncio.run(print_messages())
I think you can solve that issue by declaring the columns once, before the loop
Here’s another much-simplified example, where I pre-created all of the empty objects already inside of pre-created columns:
This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.