|
1 | 1 | """ pyplots.ai |
2 | 2 | scatter-basic: Basic Scatter Plot |
3 | 3 | Library: bokeh 3.8.1 | Python 3.13.11 |
4 | | -Quality: 100/100 | Created: 2025-12-13 |
| 4 | +Quality: 85/100 | Created: 2025-12-22 |
5 | 5 | """ |
6 | 6 |
|
7 | 7 | import numpy as np |
8 | 8 | from bokeh.io import export_png |
9 | | -from bokeh.models import ColumnDataSource |
| 9 | +from bokeh.models import ColumnDataSource, HoverTool |
10 | 10 | from bokeh.plotting import figure, output_file, save |
11 | 11 |
|
12 | 12 |
|
13 | | -# Data |
| 13 | +# Data - Study hours vs exam scores (realistic scenario) |
14 | 14 | np.random.seed(42) |
15 | | -x = np.random.randn(100) * 2 + 10 |
16 | | -y = x * 0.8 + np.random.randn(100) * 2 |
| 15 | +study_hours = np.random.uniform(1, 10, 100) |
| 16 | +exam_scores = study_hours * 8 + np.random.randn(100) * 5 + 20 |
| 17 | +exam_scores = np.clip(exam_scores, 0, 100) |
17 | 18 |
|
18 | 19 | # Create ColumnDataSource |
19 | | -source = ColumnDataSource(data={"x": x, "y": y}) |
| 20 | +source = ColumnDataSource(data={"study_hours": study_hours, "exam_scores": exam_scores}) |
20 | 21 |
|
21 | 22 | # Create figure (4800 x 2700 px for 16:9 aspect ratio) |
22 | | -p = figure( |
23 | | - width=4800, height=2700, title="scatter-basic · bokeh · pyplots.ai", x_axis_label="X Value", y_axis_label="Y Value" |
24 | | -) |
25 | | - |
26 | | -# Plot scatter points |
27 | | -p.scatter(x="x", y="y", source=source, size=15, color="#306998", alpha=0.7) |
28 | | - |
29 | | -# Styling (scaled for 4800x2700 px canvas) |
30 | | -p.title.text_font_size = "28pt" |
31 | | -p.xaxis.axis_label_text_font_size = "22pt" |
32 | | -p.yaxis.axis_label_text_font_size = "22pt" |
33 | | -p.xaxis.major_label_text_font_size = "18pt" |
34 | | -p.yaxis.major_label_text_font_size = "18pt" |
35 | | -p.grid.grid_line_alpha = 0.3 |
36 | | -p.grid.grid_line_dash = "dashed" |
| 23 | +p = figure(width=4800, height=2700, title="scatter-basic · bokeh · pyplots.ai") |
| 24 | + |
| 25 | +# Set axis labels explicitly (more reliable than figure parameters) |
| 26 | +p.xaxis.axis_label = "Study Hours (hrs)" |
| 27 | +p.yaxis.axis_label = "Exam Score (%)" |
| 28 | + |
| 29 | +# Plot scatter points (size increased for visibility on large canvas) |
| 30 | +p.scatter(x="study_hours", y="exam_scores", source=source, size=50, color="#306998", alpha=0.7) |
| 31 | + |
| 32 | +# Add HoverTool for interactivity (key Bokeh distinctive feature) |
| 33 | +hover = HoverTool(tooltips=[("Study Hours", "@study_hours{0.1} hrs"), ("Exam Score", "@exam_scores{0.1}%")]) |
| 34 | +p.add_tools(hover) |
| 35 | + |
| 36 | +# Styling (scaled for 4800x2700 px canvas - larger sizes for readability) |
| 37 | +p.title.text_font_size = "72pt" |
| 38 | +p.xaxis.axis_label_text_font_size = "48pt" |
| 39 | +p.yaxis.axis_label_text_font_size = "48pt" |
| 40 | +p.xaxis.major_label_text_font_size = "36pt" |
| 41 | +p.yaxis.major_label_text_font_size = "36pt" |
| 42 | + |
| 43 | +# Grid styling (subtle, per quality criteria VQ-07: alpha 0.2-0.4) |
| 44 | +p.grid.grid_line_alpha = 0.35 |
| 45 | +p.grid.grid_line_width = 2 |
37 | 46 |
|
38 | 47 | # Save as PNG |
39 | 48 | export_png(p, filename="plot.png") |
|
0 commit comments