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
117 changes: 117 additions & 0 deletions plots/bifurcation-basic/implementations/matplotlib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
""" pyplots.ai
bifurcation-basic: Bifurcation Diagram for Dynamical Systems
Library: matplotlib 3.10.8 | Python 3.14.3
Quality: 94/100 | Created: 2026-03-20
"""

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.colors import PowerNorm


# Data
r_min, r_max = 2.5, 4.0
num_r = 2000
transient = 200
iterations = 100

r_values = np.linspace(r_min, r_max, num_r)
r_plot = np.empty(num_r * iterations)
x_plot = np.empty(num_r * iterations)

for i, r in enumerate(r_values):
x = 0.5
for _ in range(transient):
x = r * x * (1 - x)
for j in range(iterations):
x = r * x * (1 - x)
r_plot[i * iterations + j] = r
x_plot[i * iterations + j] = x

# Create 2D histogram for density-based rendering of the chaotic region
# This reveals structure (periodic windows, attractor density) far better than scatter
r_bins = 800
x_bins = 600
hist, r_edges, x_edges = np.histogram2d(r_plot, x_plot, bins=[r_bins, x_bins], range=[[r_min, r_max], [0, 1]])

# Plot
fig, ax = plt.subplots(figsize=(16, 9))

# Subtle regime background shading
ax.axvspan(r_min, 3.0, color="#E8F4FD", alpha=0.3, zorder=0)
ax.axvspan(3.0, 3.57, color="#F0EBF8", alpha=0.3, zorder=0)
ax.axvspan(3.57, r_max, color="#FDE8E8", alpha=0.2, zorder=0)

# Density heatmap with PowerNorm to reveal structure across the full range
# cividis is perceptually uniform and colorblind-safe
ax.pcolormesh(
r_edges,
x_edges,
hist.T,
cmap="cividis",
norm=PowerNorm(gamma=0.35, vmin=0, vmax=hist.max()),
rasterized=True,
zorder=1,
)

# Regime labels at bottom with semi-transparent background for readability
label_bbox = {"boxstyle": "round,pad=0.3", "facecolor": "white", "edgecolor": "none", "alpha": 0.7}
for rx, label in [(2.75, "Stable"), (3.28, "Periodic"), (3.78, "Chaotic")]:
ax.text(
rx,
0.04,
label,
transform=ax.get_xaxis_transform(),
fontsize=14,
color="#666666",
ha="center",
va="bottom",
fontstyle="italic",
bbox=label_bbox,
zorder=3,
)

# Annotations for key bifurcation points — well spaced
bifurcation_points = [(3.0, "Period-2", -14, 0.97), (3.449, "Period-4", -60, 0.97), (3.544, "Period-8", -60, 0.87)]
for r_bif, label, x_offset, y_frac in bifurcation_points:
ax.axvline(r_bif, color="#CCCCCC", linewidth=0.8, linestyle="--", alpha=0.6, zorder=2)
ha = "right" if x_offset < 0 else "left"
ann_bbox = {"boxstyle": "round,pad=0.3", "facecolor": "white", "edgecolor": "none", "alpha": 0.8}
ax.annotate(
f"{label} r ≈ {r_bif}",
xy=(r_bif, y_frac),
xycoords=("data", "axes fraction"),
xytext=(x_offset, 0),
textcoords="offset points",
fontsize=14,
color="#444444",
ha=ha,
va="top",
bbox=ann_bbox,
zorder=4,
)

# Onset of chaos annotation
ax.annotate(
"Onset of chaos\nr ≈ 3.57",
xy=(3.57, 0.75),
xytext=(3.75, 0.93),
fontsize=14,
color="#444444",
ha="center",
bbox={"boxstyle": "round,pad=0.3", "facecolor": "white", "edgecolor": "none", "alpha": 0.8},
arrowprops={"arrowstyle": "->", "color": "#666666", "connectionstyle": "arc3,rad=-0.2"},
zorder=4,
)

# Style
ax.set_xlabel("Growth Rate (r)", fontsize=20)
ax.set_ylabel("Steady-State Population (x)", fontsize=20)
ax.set_title("bifurcation-basic · matplotlib · pyplots.ai", fontsize=24, fontweight="medium")
ax.tick_params(axis="both", labelsize=16)
ax.set_xlim(r_min, r_max)
ax.set_ylim(0, 1)
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)

plt.savefig("plot.png", dpi=300, bbox_inches="tight")
228 changes: 228 additions & 0 deletions plots/bifurcation-basic/metadata/matplotlib.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
library: matplotlib
specification_id: bifurcation-basic
created: '2026-03-20T20:28:45Z'
updated: '2026-03-20T21:08:54Z'
generated_by: claude-opus-4-5-20251101
workflow_run: 23361206203
issue: 4415
python_version: 3.14.3
library_version: 3.10.8
preview_url: https://storage.googleapis.com/pyplots-images/plots/bifurcation-basic/matplotlib/plot.png
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/bifurcation-basic/matplotlib/plot_thumb.png
preview_html: null
quality_score: 94
review:
strengths:
- Density heatmap approach (histogram2d + pcolormesh + PowerNorm) is far superior
to scatter for revealing bifurcation structure including periodic windows within
chaos
- Excellent data storytelling with regime labels, bifurcation annotations, and Onset
of chaos arrow creating a clear narrative
- Cohesive design with cividis colormap, consistent annotation styling, and subtle
regime background shading
- All spec requirements fully satisfied with appropriate parameter choices
- Clean, deterministic, well-structured code
weaknesses:
- Regime background shading (axvspan) is largely invisible in the periodic and chaotic
regions because the heatmap covers it
image_description: 'The plot displays a bifurcation diagram of the logistic map
using a density-based heatmap (pcolormesh) with the cividis colormap on a dark
blue background. The x-axis shows "Growth Rate (r)" ranging from 2.5 to 4.0, and
the y-axis shows "Steady-State Population (x)" from 0 to 1.0. The title reads
"bifurcation-basic · matplotlib · pyplots.ai" in large text at the top. The stable
fixed-point branch appears as a bright yellowish line from r=2.5 to r=3.0, then
period-doubling cascades are clearly visible as the branches split. Three regime
background shadings are subtly applied (light blue for stable, light purple for
periodic, light red for chaotic). Dashed vertical lines mark key bifurcation points
with annotations: "Period-2 r ≈ 3.0", "Period-4 r ≈ 3.449", "Period-8 r ≈ 3.544",
and "Onset of chaos r ≈ 3.57" (with an arrow). Regime labels ("Stable", "Periodic",
"Chaotic") appear at the bottom in italic with white rounded boxes. Top and right
spines are removed. The chaotic region shows rich density structure including
periodic windows.'
criteria_checklist:
visual_quality:
score: 30
max: 30
items:
- id: VQ-01
name: Text Legibility
score: 8
max: 8
passed: true
comment: 'All font sizes explicitly set: title 24pt, labels 20pt, ticks 16pt,
annotations 14pt'
- id: VQ-02
name: No Overlap
score: 6
max: 6
passed: true
comment: All annotations well-spaced, no text collisions
- id: VQ-03
name: Element Visibility
score: 6
max: 6
passed: true
comment: Density heatmap with PowerNorm reveals structure excellently across
full range
- id: VQ-04
name: Color Accessibility
score: 4
max: 4
passed: true
comment: Cividis is perceptually uniform and colorblind-safe
- id: VQ-05
name: Layout & Canvas
score: 4
max: 4
passed: true
comment: 16:9 figsize with bbox_inches tight, balanced margins
- id: VQ-06
name: Axis Labels & Title
score: 2
max: 2
passed: true
comment: 'Descriptive labels with variable names: Growth Rate (r), Steady-State
Population (x)'
design_excellence:
score: 16
max: 20
items:
- id: DE-01
name: Aesthetic Sophistication
score: 6
max: 8
passed: true
comment: Strong design with density heatmap, cividis colormap, regime shading,
cohesive annotation styling
- id: DE-02
name: Visual Refinement
score: 5
max: 6
passed: true
comment: Spines removed, no grid, subtle dashed lines, consistent bbox styling.
Regime shading partially hidden under heatmap
- id: DE-03
name: Data Storytelling
score: 5
max: 6
passed: true
comment: Clear narrative from stability to chaos with regime labels, bifurcation
annotations, and onset-of-chaos arrow
spec_compliance:
score: 15
max: 15
items:
- id: SC-01
name: Plot Type
score: 5
max: 5
passed: true
comment: Correct bifurcation diagram using density heatmap
- id: SC-02
name: Required Features
score: 4
max: 4
passed: true
comment: 'All spec requirements met: logistic map, transient discard, labeled
bifurcation points'
- id: SC-03
name: Data Mapping
score: 3
max: 3
passed: true
comment: X=parameter r, Y=state x, full range 2.5-4.0
- id: SC-04
name: Title & Legend
score: 3
max: 3
passed: true
comment: Correct title format, no legend needed for single-series density
plot
data_quality:
score: 15
max: 15
items:
- id: DQ-01
name: Feature Coverage
score: 6
max: 6
passed: true
comment: Shows stable fixed point, period-doubling cascade, chaos, and periodic
windows
- id: DQ-02
name: Realistic Context
score: 5
max: 5
passed: true
comment: Logistic map is the canonical example, real scientific context
- id: DQ-03
name: Appropriate Scale
score: 4
max: 4
passed: true
comment: 'Standard parameter ranges: r 2.5-4.0, x 0-1, 2000 r values, 200
transient, 100 iterations'
code_quality:
score: 10
max: 10
items:
- id: CQ-01
name: KISS Structure
score: 3
max: 3
passed: true
comment: Clean linear structure with no functions or classes
- id: CQ-02
name: Reproducibility
score: 2
max: 2
passed: true
comment: 'Fully deterministic: logistic map from fixed x=0.5'
- id: CQ-03
name: Clean Imports
score: 2
max: 2
passed: true
comment: All three imports used
- id: CQ-04
name: Code Elegance
score: 2
max: 2
passed: true
comment: Elegant histogram2d approach for density, no fake UI
- id: CQ-05
name: Output & API
score: 1
max: 1
passed: true
comment: Saves as plot.png with dpi=300, current API
library_mastery:
score: 8
max: 10
items:
- id: LM-01
name: Idiomatic Usage
score: 4
max: 5
passed: true
comment: Consistent Axes methods, proper fig/ax pattern, object-oriented API
- id: LM-02
name: Distinctive Features
score: 4
max: 5
passed: true
comment: PowerNorm, pcolormesh, axvspan, annotate with mixed coordinate systems
verdict: APPROVED
impl_tags:
dependencies: []
techniques:
- annotations
- layer-composition
patterns:
- data-generation
- matrix-construction
dataprep:
- binning
styling:
- custom-colormap
- alpha-blending
Loading