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")
# Visualization selector
viz_type = st.selectbox(
"Select Visualization",
["Spiral Helix", "Surface Plot", "3D Clusters"]
)
# Sidebar controls
st.sidebar.header("Plot Controls")
# Common controls
point_size = st.sidebar.slider("Point Size", 1, 20, 5)
opacity = st.sidebar.slider("Opacity", 0.0, 1.0, 0.8)
colorscale = st.sidebar.selectbox(
"Color Scheme",
["Viridis", "Plasma", "Inferno", "Magma", "Rainbow"]
)
# Generate data based on selected visualization
def generate_helix(n_points=100, noise=0.1):
t = np.linspace(0, 10*np.pi, n_points)
x = np.cos(t) + np.random.normal(0, noise, n_points)
y = np.sin(t) + np.random.normal(0, noise, n_points)
z = t/3 + np.random.normal(0, noise, n_points)
return x, y, z
def generate_surface(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(-5, 5, 3)
cluster = np.random.normal(center, 1, (points_per_cluster, 3))
clusters.append(cluster)
return np.vstack(clusters)
if viz_type == "Spiral Helix":
# Additional controls for helix
noise_level = st.sidebar.slider("Noise Level", 0.0, 0.5, 0.1)
rotation_speed = st.sidebar.slider("Animation Speed", 0, 100, 50)
# Generate data
x, y, z = generate_helix(noise=noise_level)
# Create figure
fig = go.Figure(data=[go.Scatter3d(
x=x, y=y, z=z,
mode='markers',
marker=dict(
size=point_size,
opacity=opacity,
color=z,
colorscale=colorscale.lower(),
)
)])
elif viz_type == "Surface Plot":
# Additional controls for surface
resolution = st.sidebar.slider("Resolution", 20, 100, 50)
show_contours = st.sidebar.checkbox("Show Contours", True)
# Generate data
X, Y, Z = generate_surface(resolution)
# Create figure
fig = go.Figure(data=[go.Surface(
x=X, y=Y, z=Z,
opacity=opacity,
colorscale=colorscale.lower(),
contours=dict(
z=dict(
show=show_contours,
usecolormap=True,
project_z=True
)
)
)])
else: # 3D Clusters
# Additional controls for clusters
n_clusters = st.sidebar.slider("Number of Clusters", 2, 5, 3)
points_per_cluster = st.sidebar.slider("Points per Cluster", 20, 100, 50)
# Generate data
data = generate_clusters(n_clusters, points_per_cluster)
# Create figure
fig = go.Figure(data=[go.Scatter3d(
x=data[:, 0], y=data[:, 1], z=data[:, 2],
mode='markers',
marker=dict(
size=point_size,
opacity=opacity,
color=np.repeat(range(n_clusters), points_per_cluster),
colorscale=colorscale.lower(),
)
)])
# Update layout for all plots
fig.update_layout(
scene=dict(
xaxis_title="X",
yaxis_title="Y",
zaxis_title="Z",
aspectmode='cube'
),
width=800,
height=800,
margin=dict(l=0, r=0, b=0, t=30)
)
# Display plot
st.plotly_chart(fig, use_container_width=True)
# Add description based on visualization type
if viz_type == "Spiral Helix":
st.markdown("""
**Spiral Helix Visualization**
- 3D helix with configurable random noise
- Color mapped to z-coordinate
- Fully interactive: rotate, zoom, and pan
""")
elif viz_type == "Surface Plot":
st.markdown("""
**Surface Plot Visualization**
- Surface defined by z = sin(x)*cos(y)
- Optional contour lines
- Adjustable resolution
""")
else:
st.markdown("""
**3D Clusters Visualization**
- Randomly generated clusters in 3D space
- Configurable number of clusters and points
- Each cluster shown in different color
""")
Hi! I can help you with any questions about Streamlit and Python. What would you like to know?