From 4d984997f96560e1bf25bd10681f14afd0804dac Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 9 Jan 2026 09:07:51 +0000 Subject: [PATCH 1/3] feat(highcharts): implement heatmap-interactive --- .../implementations/highcharts.py | 226 ++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 plots/heatmap-interactive/implementations/highcharts.py diff --git a/plots/heatmap-interactive/implementations/highcharts.py b/plots/heatmap-interactive/implementations/highcharts.py new file mode 100644 index 0000000000..c163148867 --- /dev/null +++ b/plots/heatmap-interactive/implementations/highcharts.py @@ -0,0 +1,226 @@ +"""pyplots.ai +heatmap-interactive: Interactive Heatmap with Hover and Zoom +Library: highcharts | Python 3.13 +Quality: pending | Created: 2025-01-09 +""" + +import tempfile +import time +import urllib.request +from pathlib import Path + +import numpy as np +from highcharts_core.chart import Chart +from highcharts_core.options import HighchartsOptions +from selenium import webdriver +from selenium.webdriver.chrome.options import Options + + +# Data - Monthly website traffic by hour and day (20x24 matrix) +np.random.seed(42) +days = [ + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + "Sunday", + "Week 2 Mon", + "Week 2 Tue", + "Week 2 Wed", + "Week 2 Thu", + "Week 2 Fri", + "Week 2 Sat", + "Week 2 Sun", + "Week 3 Mon", + "Week 3 Tue", + "Week 3 Wed", + "Week 3 Thu", + "Week 3 Fri", + "Week 3 Sat", +] +hours = [f"{h:02d}:00" for h in range(24)] + +# Generate realistic traffic patterns +base_traffic = np.zeros((len(days), len(hours))) +for i, day in enumerate(days): + for j in range(len(hours)): + # Peak hours 9-17 on weekdays + is_weekend = "Sat" in day or "Sun" in day + hour_factor = 1.0 + if 9 <= j <= 17: + hour_factor = 2.5 if not is_weekend else 1.5 + elif 6 <= j <= 8 or 18 <= j <= 21: + hour_factor = 1.8 if not is_weekend else 1.3 + elif 0 <= j <= 5: + hour_factor = 0.3 + + day_factor = 0.6 if is_weekend else 1.0 + base_value = 500 * day_factor * hour_factor + noise = np.random.normal(0, base_value * 0.2) + base_traffic[i, j] = max(0, base_value + noise) + +# Convert to heatmap data format for Highcharts +heatmap_data = [] +for i, _day in enumerate(days): + for j, _hour in enumerate(hours): + heatmap_data.append([j, i, round(base_traffic[i, j], 1)]) + +# Download Highcharts JS and heatmap module +highcharts_url = "https://code.highcharts.com/highcharts.js" +heatmap_url = "https://code.highcharts.com/modules/heatmap.js" +boost_url = "https://code.highcharts.com/modules/boost.js" + +with urllib.request.urlopen(highcharts_url, timeout=30) as response: + highcharts_js = response.read().decode("utf-8") +with urllib.request.urlopen(heatmap_url, timeout=30) as response: + heatmap_js = response.read().decode("utf-8") +with urllib.request.urlopen(boost_url, timeout=30) as response: + boost_js = response.read().decode("utf-8") + +# Create chart +chart = Chart(container="container") +chart.options = HighchartsOptions() + +# Chart configuration with zooming +chart.options.chart = { + "type": "heatmap", + "width": 4800, + "height": 2700, + "backgroundColor": "#ffffff", + "zoomType": "xy", + "panning": {"enabled": True, "type": "xy"}, + "panKey": "shift", + "marginBottom": 180, + "resetZoomButton": { + "position": {"align": "right", "verticalAlign": "top", "x": -60, "y": 60}, + "theme": {"fill": "#306998", "stroke": "#306998", "style": {"color": "#ffffff", "fontSize": "20px"}}, + }, +} + +# Title +chart.options.title = { + "text": "Website Traffic by Hour · heatmap-interactive · highcharts · pyplots.ai", + "style": {"fontSize": "48px", "fontWeight": "bold"}, +} + +chart.options.subtitle = { + "text": "Drag to zoom, Shift+drag to pan, click reset button to restore view", + "style": {"fontSize": "28px", "color": "#666666"}, +} + +# X-axis (hours) +chart.options.x_axis = { + "categories": hours, + "title": {"text": "Hour of Day", "style": {"fontSize": "32px"}}, + "labels": {"style": {"fontSize": "22px"}, "rotation": 315}, + "tickLength": 0, + "gridLineWidth": 0, +} + +# Y-axis (days) +chart.options.y_axis = { + "categories": days, + "title": {"text": "Day", "style": {"fontSize": "32px"}}, + "labels": {"style": {"fontSize": "22px"}}, + "reversed": True, + "gridLineWidth": 0, +} + +# Color axis (legend) +chart.options.color_axis = { + "min": 0, + "max": float(np.max(base_traffic)), + "stops": [[0, "#f7fbff"], [0.2, "#c6dbef"], [0.4, "#6baed6"], [0.6, "#2171b5"], [0.8, "#08519c"], [1, "#08306b"]], + "labels": {"style": {"fontSize": "22px"}}, +} + +# Legend +chart.options.legend = { + "align": "right", + "layout": "vertical", + "verticalAlign": "middle", + "symbolHeight": 600, + "itemStyle": {"fontSize": "22px"}, + "title": {"text": "Visitors", "style": {"fontSize": "26px"}}, +} + +# Tooltip +chart.options.tooltip = { + "useHTML": True, + "headerFormat": "", + "pointFormat": '
{series.xAxis.categories.(point.x)} on {series.yAxis.categories.(point.y)}
Visitors: {point.value:.0f}
', + "backgroundColor": "rgba(255, 255, 255, 0.95)", + "borderWidth": 2, + "borderColor": "#306998", +} + +# Plot options for heatmap +chart.options.plot_options = { + "heatmap": { + "borderWidth": 1, + "borderColor": "#ffffff", + "dataLabels": {"enabled": False}, + "cursor": "pointer", + "states": {"hover": {"brightness": 0.2, "borderColor": "#000000", "borderWidth": 3}}, + } +} + +# Add series +chart.add_series({"name": "Traffic", "type": "heatmap", "data": heatmap_data, "turboThreshold": 10000}) + +# Generate HTML with inline scripts +html_str = chart.to_js_literal() +html_content = f""" + + + + + + + + +
+ + +""" + +# Save interactive HTML +with open("plot.html", "w", encoding="utf-8") as f: + # Generate standalone HTML with CDN links for the interactive version + interactive_html = f""" + + + + heatmap-interactive · highcharts · pyplots.ai + + + + + +
+ + +""" + f.write(interactive_html) + +# Write temp HTML and take screenshot +with tempfile.NamedTemporaryFile(mode="w", suffix=".html", delete=False, encoding="utf-8") as f: + f.write(html_content) + temp_path = f.name + +chrome_options = Options() +chrome_options.add_argument("--headless") +chrome_options.add_argument("--no-sandbox") +chrome_options.add_argument("--disable-dev-shm-usage") +chrome_options.add_argument("--disable-gpu") +chrome_options.add_argument("--window-size=4800,2900") + +driver = webdriver.Chrome(options=chrome_options) +driver.get(f"file://{temp_path}") +time.sleep(5) +driver.save_screenshot("plot.png") +driver.quit() + +Path(temp_path).unlink() From d77ee362a07027936f361271c22d9e5bb4ccf57a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 9 Jan 2026 09:08:06 +0000 Subject: [PATCH 2/3] chore(highcharts): add metadata for heatmap-interactive --- .../metadata/highcharts.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 plots/heatmap-interactive/metadata/highcharts.yaml diff --git a/plots/heatmap-interactive/metadata/highcharts.yaml b/plots/heatmap-interactive/metadata/highcharts.yaml new file mode 100644 index 0000000000..42167268b8 --- /dev/null +++ b/plots/heatmap-interactive/metadata/highcharts.yaml @@ -0,0 +1,19 @@ +# Per-library metadata for highcharts implementation of heatmap-interactive +# Auto-generated by impl-generate.yml + +library: highcharts +specification_id: heatmap-interactive +created: '2026-01-09T09:08:06Z' +updated: '2026-01-09T09:08:06Z' +generated_by: claude-opus-4-5-20251101 +workflow_run: 20846719177 +issue: 3289 +python_version: 3.13.11 +library_version: unknown +preview_url: https://storage.googleapis.com/pyplots-images/plots/heatmap-interactive/highcharts/plot.png +preview_thumb: https://storage.googleapis.com/pyplots-images/plots/heatmap-interactive/highcharts/plot_thumb.png +preview_html: https://storage.googleapis.com/pyplots-images/plots/heatmap-interactive/highcharts/plot.html +quality_score: null +review: + strengths: [] + weaknesses: [] From 7b46d1702e14afe28d8a258fdb245abf616dc728 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 9 Jan 2026 09:11:00 +0000 Subject: [PATCH 3/3] chore(highcharts): update quality score 91 and review feedback for heatmap-interactive --- .../implementations/highcharts.py | 6 +- .../metadata/highcharts.yaml | 206 +++++++++++++++++- 2 files changed, 202 insertions(+), 10 deletions(-) diff --git a/plots/heatmap-interactive/implementations/highcharts.py b/plots/heatmap-interactive/implementations/highcharts.py index c163148867..f7f2ad42b3 100644 --- a/plots/heatmap-interactive/implementations/highcharts.py +++ b/plots/heatmap-interactive/implementations/highcharts.py @@ -1,7 +1,7 @@ -"""pyplots.ai +""" pyplots.ai heatmap-interactive: Interactive Heatmap with Hover and Zoom -Library: highcharts | Python 3.13 -Quality: pending | Created: 2025-01-09 +Library: highcharts unknown | Python 3.13.11 +Quality: 91/100 | Created: 2026-01-09 """ import tempfile diff --git a/plots/heatmap-interactive/metadata/highcharts.yaml b/plots/heatmap-interactive/metadata/highcharts.yaml index 42167268b8..ce065477d3 100644 --- a/plots/heatmap-interactive/metadata/highcharts.yaml +++ b/plots/heatmap-interactive/metadata/highcharts.yaml @@ -1,10 +1,7 @@ -# Per-library metadata for highcharts implementation of heatmap-interactive -# Auto-generated by impl-generate.yml - library: highcharts specification_id: heatmap-interactive created: '2026-01-09T09:08:06Z' -updated: '2026-01-09T09:08:06Z' +updated: '2026-01-09T09:10:59Z' generated_by: claude-opus-4-5-20251101 workflow_run: 20846719177 issue: 3289 @@ -13,7 +10,202 @@ library_version: unknown preview_url: https://storage.googleapis.com/pyplots-images/plots/heatmap-interactive/highcharts/plot.png preview_thumb: https://storage.googleapis.com/pyplots-images/plots/heatmap-interactive/highcharts/plot_thumb.png preview_html: https://storage.googleapis.com/pyplots-images/plots/heatmap-interactive/highcharts/plot.html -quality_score: null +quality_score: 91 review: - strengths: [] - weaknesses: [] + strengths: + - 'Excellent use of Highcharts interactive features: zoom/pan, tooltips, reset button, + hover highlighting' + - Clean blue sequential colormap that is colorblind-safe + - Realistic website traffic data with clear weekday/weekend and day/night patterns + - Well-structured code with proper inline JS embedding for Selenium screenshot + - Good cell sizing with white borders for clear separation + weaknesses: + - Title format has descriptive prefix before the spec-id format + - Legend title lacks units (e.g., Visitors count) + - Could utilize Highcharts boost module more effectively for performance demonstration + image_description: The plot displays an interactive heatmap showing website traffic + data by hour of day (x-axis, 24 hours from 00:00 to 23:00) and day (y-axis, 20 + days spanning Monday through Week 3 Sat). The heatmap uses a blue sequential color + scale ranging from very light blue/white (low values ~0) to dark navy blue (high + values ~2250 visitors). The title reads "Website Traffic by Hour · heatmap-interactive + · highcharts · pyplots.ai" with a subtitle explaining zoom/pan controls. A vertical + color legend labeled "Visitors" appears on the right side. Clear patterns show + higher traffic during business hours (9-17) on weekdays and lower traffic overnight + and on weekends. X-axis labels are rotated at 315 degrees for readability. White + borders separate each cell. + criteria_checklist: + visual_quality: + score: 37 + max: 40 + items: + - id: VQ-01 + name: Text Legibility + score: 9 + max: 10 + passed: true + comment: Title, axis labels, and legend are readable; tick labels slightly + small but acceptable + - id: VQ-02 + name: No Overlap + score: 8 + max: 8 + passed: true + comment: No overlapping text elements; rotated x-axis labels are well-spaced + - id: VQ-03 + name: Element Visibility + score: 8 + max: 8 + passed: true + comment: Heatmap cells are well-sized with clear color differentiation and + white borders + - id: VQ-04 + name: Color Accessibility + score: 5 + max: 5 + passed: true + comment: Blue sequential colormap is colorblind-safe + - id: VQ-05 + name: Layout Balance + score: 5 + max: 5 + passed: true + comment: Plot fills canvas well, legend positioned appropriately on right + - id: VQ-06 + name: Axis Labels + score: 2 + max: 2 + passed: true + comment: Hour of Day and Day are descriptive + - id: VQ-07 + name: Grid & Legend + score: 0 + max: 2 + passed: false + comment: No grid lines (acceptable for heatmap), but legend title lacks units + spec_compliance: + score: 23 + max: 25 + items: + - id: SC-01 + name: Plot Type + score: 8 + max: 8 + passed: true + comment: Correct heatmap chart type + - id: SC-02 + name: Data Mapping + score: 5 + max: 5 + passed: true + comment: X=hours, Y=days, value=traffic correctly mapped + - id: SC-03 + name: Required Features + score: 4 + max: 5 + passed: true + comment: Has hover tooltips, zoom/pan, reset button; crosshair/highlight on + hover implemented via brightness change + - id: SC-04 + name: Data Range + score: 3 + max: 3 + passed: true + comment: All data visible, colorbar shows full range 0-2250 + - id: SC-05 + name: Legend Accuracy + score: 2 + max: 2 + passed: true + comment: Legend correctly shows Visitors with proper scale + - id: SC-06 + name: Title Format + score: 1 + max: 2 + passed: false + comment: Title uses descriptive text before spec-id instead of just spec-id + format + data_quality: + score: 19 + max: 20 + items: + - id: DQ-01 + name: Feature Coverage + score: 7 + max: 8 + passed: true + comment: Shows weekday/weekend patterns, hourly patterns, good variation; + could show more extreme outliers + - id: DQ-02 + name: Realistic Context + score: 7 + max: 7 + passed: true + comment: Website traffic by hour/day is a realistic, neutral scenario + - id: DQ-03 + name: Appropriate Scale + score: 5 + max: 5 + passed: true + comment: Visitor counts 0-2250 are realistic for hourly website traffic + code_quality: + score: 9 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + passed: true + comment: Linear script structure, no functions/classes + - id: CQ-02 + name: Reproducibility + score: 3 + max: 3 + passed: true + comment: np.random.seed(42) set + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: All imports are used + - id: CQ-04 + name: No Deprecated API + score: 1 + max: 1 + passed: true + comment: Uses current highcharts-core API + - id: CQ-05 + name: Output Correct + score: 0 + max: 1 + passed: false + comment: Saves plot.png but also creates plot.html (acceptable for interactive + library) + library_features: + score: 3 + max: 5 + items: + - id: LF-01 + name: Distinctive Features + score: 3 + max: 5 + passed: true + comment: Uses Highcharts heatmap module, zoom/pan, tooltips, reset button, + hover states; could utilize boost module more effectively + verdict: APPROVED +impl_tags: + dependencies: + - selenium + techniques: + - hover-tooltips + - html-export + - colorbar + patterns: + - data-generation + - matrix-construction + - iteration-over-groups + dataprep: [] + styling: + - custom-colormap + - edge-highlighting