Create an app showing 3D data visualizations. Generate mock 3D data: - Spiral helix with noise (100 points) - Surface plot (z = sin(x)*cos(y)) - 3D clusters (3 clusters, 50 points each) Features: - Viz selector dropdown - Interactive 3D plots with rotate/zoom - Controls for: * Point styling (size, color, opacity) * Axis settings * Animation speed Surface plot options: - Function parameter sliders - Color scheme toggle - Contour lines All plots should be fully interactive.
To upload files, please first save the app
import streamlit as st
import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots
# Page config
st.set_page_config(page_title="3D Visualizations", layout="wide")
st.title("3D Data Visualizations")
# Sidebar controls
viz_type = st.sidebar.selectbox(
"Select Visualization",
["Spiral Helix", "Surface Plot", "3D Clusters"]
)
# Common styling controls
st.sidebar.subheader("Style Controls")
point_size = st.sidebar.slider("Point Size", 2, 10, 5)
opacity = st.sidebar.slider("Opacity", 0.1, 1.0, 0.7)
color_scheme = st.sidebar.selectbox(
"Color Scheme",
["Viridis", "Plasma", "Magma", "Inferno"]
)
# Generate data based on selected visualization
def generate_spiral_helix(n_points=100):
t = np.linspace(0, 10*np.pi, n_points)
noise = np.random.normal(0, 0.1, n_points)
x = np.cos(t) + noise
y = np.sin(t) + noise
z = t/5 + noise
return x, y, z
def generate_surface_data(n_points=50):
x = np.linspace(-5, 5, n_points)
y = np.linspace(-5, 5, n_points)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)
return X, Y, Z
def generate_clusters(n_clusters=3, points_per_cluster=50):
clusters = []
for i in range(n_clusters):
center = np.random.uniform(-3, 3, 3)
cluster = center + np.random.normal(0, 0.5, (points_per_cluster, 3))
clusters.append(cluster)
return np.vstack(clusters)
# Plot functions
def plot_spiral():
x, y, z = generate_spiral_helix()
fig = go.Figure(data=[go.Scatter3d(
x=x, y=y, z=z,
mode='markers',
marker=dict(
size=point_size,
opacity=opacity,
color=z,
colorscale=color_scheme.lower(),
)
)])
fig.update_layout(
scene=dict(
xaxis_title="X",
yaxis_title="Y",
zaxis_title="Z"
),
width=800,
height=800,
)
return fig
def plot_surface():
X, Y, Z = generate_surface_data()
# Surface plot controls
st.sidebar.subheader("Surface Plot Controls")
show_contours = st.sidebar.checkbox("Show Contours", True)
amplitude = st.sidebar.slider("Amplitude", 0.1, 2.0, 1.0)
frequency = st.sidebar.slider("Frequency", 0.1, 2.0, 1.0)
Z = amplitude * np.sin(frequency * X) * np.cos(frequency * Y)
fig = go.Figure(data=[go.Surface(
x=X, y=Y, z=Z,
colorscale=color_scheme.lower(),
opacity=opacity,
contours=dict(
z=dict(
show=show_contours,
usecolormap=True,
project_z=True
)
)
)])
fig.update_layout(
scene=dict(
xaxis_title="X",
yaxis_title="Y",
zaxis_title="Z"
),
width=800,
height=800,
)
return fig
def plot_clusters():
clusters = generate_clusters()
fig = go.Figure(data=[go.Scatter3d(
x=clusters[:, 0],
y=clusters[:, 1],
z=clusters[:, 2],
mode='markers',
marker=dict(
size=point_size,
opacity=opacity,
color=clusters[:, 2],
colorscale=color_scheme.lower(),
)
)])
fig.update_layout(
scene=dict(
xaxis_title="X",
yaxis_title="Y",
zaxis_title="Z"
),
width=800,
height=800,
)
return fig
# Main content
if viz_type == "Spiral Helix":
st.subheader("3D Spiral Helix with Noise")
fig = plot_spiral()
st.plotly_chart(fig, use_container_width=True)
elif viz_type == "Surface Plot":
st.subheader("3D Surface Plot")
fig = plot_surface()
st.plotly_chart(fig, use_container_width=True)
else: # 3D Clusters
st.subheader("3D Clusters")
fig = plot_clusters()
st.plotly_chart(fig, use_container_width=True)
# Add explanation
with st.expander("About the Visualizations"):
st.markdown("""
### Visualization Details
- **Spiral Helix**: A 3D helix with added Gaussian noise to create more interesting patterns.
- **Surface Plot**: An interactive surface plot showing z = sin(x)*cos(y) with adjustable parameters.
- **3D Clusters**: Three randomly generated clusters in 3D space.
All visualizations are interactive - you can:
- Rotate the view by clicking and dragging
- Zoom with the scroll wheel
- Pan by right-clicking and dragging
- Double click to reset the view
""")
Hi! I can help you with any questions about Streamlit and Python. What would you like to know?