Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 113 additions & 44 deletions plots/scatter-marginal/implementations/python/plotly.py
Original file line number Diff line number Diff line change
@@ -1,64 +1,133 @@
""" pyplots.ai
""" anyplot.ai
scatter-marginal: Scatter Plot with Marginal Distributions
Library: plotly 6.5.0 | Python 3.13.11
Quality: 92/100 | Created: 2025-12-26
Library: plotly 6.7.0 | Python 3.13.13
Quality: 92/100 | Updated: 2026-05-09
"""

import os
import sys

import numpy as np
import plotly.express as px


# Data - Bivariate normal with correlation
try:
import plotly.graph_objects as go
except ImportError:
__file__ = os.path.abspath(__file__)
__dir__ = os.path.dirname(__file__)
if __dir__ in sys.path:
sys.path.remove(__dir__)
import plotly.graph_objects as go

# Theme tokens
THEME = os.getenv("ANYPLOT_THEME", "light")
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
GRID = "rgba(26,26,23,0.10)" if THEME == "light" else "rgba(240,239,232,0.10)"
BRAND = "#009E73"

# Data - Bivariate normal with correlation (scientific measurement scenario)
np.random.seed(42)
n = 200
x = np.random.randn(n) * 10 + 50
y = 0.7 * x + np.random.randn(n) * 8 + 15
# Temperature (°C) and relative humidity (%)
temperature = np.random.randn(n) * 3.5 + 22
humidity = 0.65 * temperature + np.random.randn(n) * 6 + 35

# Create scatter plot with marginal histograms
fig = px.scatter(x=x, y=y, marginal_x="histogram", marginal_y="histogram")
# Create scatter plot with marginal histograms using go (for full control)
fig = go.Figure()

# Style main scatter plot
fig.update_traces(
marker={"size": 14, "color": "#306998", "opacity": 0.65, "line": {"width": 1, "color": "#1e4a6e"}},
selector={"type": "scatter", "mode": "markers"},
# Add scatter trace
fig.add_trace(
go.Scatter(
x=temperature,
y=humidity,
mode="markers",
marker=dict(size=14, color=BRAND, opacity=0.65, line=dict(width=1, color=PAGE_BG)),
name="Measurements",
showlegend=False,
)
)

# Add marginal histogram for X (temperature)
fig.add_trace(
go.Histogram(
x=temperature,
name="Temp Distribution",
marker=dict(color=BRAND, opacity=0.6),
yaxis="y2",
xaxis="x",
showlegend=False,
nbinsx=25,
)
)

# Add marginal histogram for Y (humidity)
fig.add_trace(
go.Histogram(
y=humidity,
name="Humidity Distribution",
marker=dict(color=BRAND, opacity=0.6),
xaxis="x2",
yaxis="y",
showlegend=False,
nbinsy=25,
orientation="h",
)
)

# Style marginal histograms
# Enhanced hover tooltips for better data storytelling
fig.update_traces(
marker={"color": "#306998", "opacity": 0.7, "line": {"width": 1, "color": "#1e4a6e"}},
selector={"type": "histogram"},
hovertemplate="<b>Measurement</b><br>Temperature: %{x:.1f}°C<br>Humidity: %{y:.1f}%<extra></extra>",
selector=dict(mode="markers"),
)

# Layout for 4800x2700 px
# Update layout with refined design: spine removal, subtle grid, publication-grade styling
fig.update_layout(
title={
"text": "scatter-marginal \u00b7 plotly \u00b7 pyplots.ai",
"font": {"size": 32},
"x": 0.5,
"xanchor": "center",
},
xaxis={
"title": {"text": "X Value", "font": {"size": 24}},
"tickfont": {"size": 18},
"gridcolor": "rgba(128, 128, 128, 0.3)",
"gridwidth": 1,
},
yaxis={
"title": {"text": "Y Value", "font": {"size": 24}},
"tickfont": {"size": 18},
"gridcolor": "rgba(128, 128, 128, 0.3)",
"gridwidth": 1,
},
xaxis2={"tickfont": {"size": 14}},
yaxis2={"tickfont": {"size": 14}},
xaxis3={"tickfont": {"size": 14}},
yaxis3={"tickfont": {"size": 14}},
template="plotly_white",
font={"family": "Arial, sans-serif"},
title=dict(text="scatter-marginal · plotly · anyplot.ai", font=dict(size=28, color=INK), x=0.5, xanchor="center"),
xaxis=dict(
domain=[0, 0.85],
title=dict(text="Temperature (°C)", font=dict(size=22, color=INK)),
tickfont=dict(size=18, color=INK_SOFT),
gridcolor=GRID,
linecolor=INK_SOFT,
showgrid=True,
gridwidth=0.5,
showline=True,
linewidth=1.5,
mirror=False,
side="bottom",
),
yaxis=dict(
domain=[0, 0.85],
title=dict(text="Relative Humidity (%)", font=dict(size=22, color=INK)),
tickfont=dict(size=18, color=INK_SOFT),
gridcolor=GRID,
linecolor=INK_SOFT,
showgrid=True,
gridwidth=0.5,
showline=True,
linewidth=1.5,
mirror=False,
side="left",
),
xaxis2=dict(
domain=[0.85, 1], showticklabels=False, gridcolor=GRID, linecolor=INK_SOFT, showgrid=False, showline=False
),
yaxis2=dict(
domain=[0.85, 1], showticklabels=False, gridcolor=GRID, linecolor=INK_SOFT, showgrid=False, showline=False
),
paper_bgcolor=PAGE_BG,
plot_bgcolor=PAGE_BG,
font=dict(family="Arial, sans-serif", color=INK),
showlegend=False,
margin={"l": 100, "r": 100, "t": 120, "b": 100},
margin=dict(l=120, r=80, t=100, b=100),
height=900,
width=1600,
hovermode="closest",
)

# Save
fig.write_image("plot.png", width=1600, height=900, scale=3)
fig.write_html("plot.html", include_plotlyjs="cdn")
fig.write_image(f"plot-{THEME}.png", width=1600, height=900, scale=3)
fig.write_html(f"plot-{THEME}.html", include_plotlyjs="cdn")
Loading
Loading