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 sklearn.datasets import make_blobs
import plotly.express as px
st.title("3D Data Visualization")
# 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)
colorscale = st.sidebar.selectbox(
"Color Scheme",
["Viridis", "Plasma", "Inferno", "Magma", "Cividis"]
)
# Generate spiral helix data
def generate_helix(n_points=100, noise=0.1):
t = np.linspace(0, 10*np.pi, n_points)
x = np.cos(t)
y = np.sin(t)
z = t/10
# Add noise
x += np.random.normal(0, noise, n_points)
y += np.random.normal(0, noise, n_points)
z += np.random.normal(0, noise, n_points)
return x, y, z
# Generate surface plot data
def generate_surface(x_range=(-5, 5), y_range=(-5, 5), n_points=100):
x = np.linspace(x_range[0], x_range[1], n_points)
y = np.linspace(y_range[0], y_range[1], n_points)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)
return X, Y, Z
# Generate cluster data
def generate_clusters(n_clusters=3, n_points=50):
X, y = make_blobs(n_samples=n_points*n_clusters, centers=n_clusters,
n_features=3, random_state=42)
return X[:, 0], X[:, 1], X[:, 2], y
if viz_type == "Spiral Helix":
st.subheader("3D Spiral Helix with Noise")
noise_level = st.sidebar.slider("Noise Level", 0.0, 0.5, 0.1)
rotation_speed = st.sidebar.slider("Animation Speed", 0, 100, 50)
x, y, z = generate_helix(noise=noise_level)
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":
st.subheader("3D Surface Plot")
freq_x = st.sidebar.slider("X Frequency", 0.1, 2.0, 1.0)
freq_y = st.sidebar.slider("Y Frequency", 0.1, 2.0, 1.0)
show_contours = st.sidebar.checkbox("Show Contours", False)
X, Y, Z = generate_surface()
Z = np.sin(X * freq_x) * np.cos(Y * freq_y)
fig = go.Figure(data=[go.Surface(
x=X, y=Y, z=Z,
colorscale=colorscale.lower(),
opacity=opacity,
contours=dict(
z=dict(
show=show_contours,
usecolormap=True,
project_z=True
)
)
)])
else: # 3D Clusters
st.subheader("3D Clusters")
n_points = st.sidebar.slider("Points per Cluster", 20, 100, 50)
x, y, z, labels = generate_clusters(n_points=n_points)
fig = go.Figure(data=[go.Scatter3d(
x=x, y=y, z=z,
mode='markers',
marker=dict(
size=point_size,
opacity=opacity,
color=labels,
colorscale=colorscale.lower(),
)
)])
# Common figure layout settings
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 the plot
st.plotly_chart(fig, use_container_width=True)
# Add info about interactivity
st.info("💡 You can interact with the plot using your mouse/touchpad:\n"
"- Click and drag to rotate\n"
"- Scroll to zoom\n"
"- Right-click and drag to pan")
Hi! I can help you with any questions about Streamlit and Python. What would you like to know?