|
| 1 | +""" pyplots.ai |
| 2 | +line-markers: Line Plot with Markers |
| 3 | +Library: bokeh 3.8.1 | Python 3.13.11 |
| 4 | +Quality: 92/100 | Created: 2025-12-30 |
| 5 | +""" |
| 6 | + |
| 7 | +import numpy as np |
| 8 | +from bokeh.io import export_png, save |
| 9 | +from bokeh.models import ColumnDataSource, Legend |
| 10 | +from bokeh.plotting import figure |
| 11 | + |
| 12 | + |
| 13 | +# Data - Monthly temperature readings for three weather stations |
| 14 | +np.random.seed(42) |
| 15 | +months = np.arange(1, 13) |
| 16 | +month_labels = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] |
| 17 | + |
| 18 | +# Temperature patterns for different stations (°C) |
| 19 | +base_temp = np.array([2, 4, 8, 12, 17, 21, 24, 23, 19, 13, 7, 3]) |
| 20 | +station_a = base_temp + np.random.randn(12) * 1.5 |
| 21 | +station_b = base_temp + 3 + np.random.randn(12) * 1.5 # Warmer station |
| 22 | +station_c = base_temp - 2 + np.random.randn(12) * 1.5 # Cooler station |
| 23 | + |
| 24 | +# Create ColumnDataSources |
| 25 | +source_a = ColumnDataSource(data={"x": months, "y": station_a}) |
| 26 | +source_b = ColumnDataSource(data={"x": months, "y": station_b}) |
| 27 | +source_c = ColumnDataSource(data={"x": months, "y": station_c}) |
| 28 | + |
| 29 | +# Create figure |
| 30 | +p = figure( |
| 31 | + width=4800, |
| 32 | + height=2700, |
| 33 | + title="line-markers · bokeh · pyplots.ai", |
| 34 | + x_axis_label="Month", |
| 35 | + y_axis_label="Temperature (°C)", |
| 36 | +) |
| 37 | + |
| 38 | +# Color palette |
| 39 | +color_a = "#306998" # Python Blue |
| 40 | +color_b = "#FFD43B" # Python Yellow |
| 41 | +color_c = "#E74C3C" # Colorblind-safe red |
| 42 | + |
| 43 | +# Plot lines with markers - Station A (circles) |
| 44 | +line_a = p.line("x", "y", source=source_a, line_width=4, color=color_a, alpha=0.9) |
| 45 | +scatter_a = p.scatter("x", "y", source=source_a, size=20, color=color_a, marker="circle", alpha=0.9) |
| 46 | + |
| 47 | +# Station B (squares) |
| 48 | +line_b = p.line("x", "y", source=source_b, line_width=4, color=color_b, alpha=0.9) |
| 49 | +scatter_b = p.scatter("x", "y", source=source_b, size=20, color=color_b, marker="square", alpha=0.9) |
| 50 | + |
| 51 | +# Station C (triangles) |
| 52 | +line_c = p.line("x", "y", source=source_c, line_width=4, color=color_c, alpha=0.9) |
| 53 | +scatter_c = p.scatter("x", "y", source=source_c, size=20, color=color_c, marker="triangle", alpha=0.9) |
| 54 | + |
| 55 | +# Legend |
| 56 | +legend = Legend( |
| 57 | + items=[("Station A", [line_a, scatter_a]), ("Station B", [line_b, scatter_b]), ("Station C", [line_c, scatter_c])], |
| 58 | + location="top_left", |
| 59 | +) |
| 60 | + |
| 61 | +p.add_layout(legend) |
| 62 | +p.legend.label_text_font_size = "20pt" |
| 63 | +p.legend.glyph_height = 30 |
| 64 | +p.legend.glyph_width = 30 |
| 65 | +p.legend.spacing = 10 |
| 66 | +p.legend.padding = 15 |
| 67 | +p.legend.background_fill_alpha = 0.7 |
| 68 | + |
| 69 | +# Style text for 4800x2700 canvas |
| 70 | +p.title.text_font_size = "28pt" |
| 71 | +p.xaxis.axis_label_text_font_size = "22pt" |
| 72 | +p.yaxis.axis_label_text_font_size = "22pt" |
| 73 | +p.xaxis.major_label_text_font_size = "18pt" |
| 74 | +p.yaxis.major_label_text_font_size = "18pt" |
| 75 | + |
| 76 | +# Custom x-axis tick labels for months |
| 77 | +p.xaxis.ticker = months |
| 78 | +p.xaxis.major_label_overrides = dict(zip(months, month_labels, strict=True)) |
| 79 | + |
| 80 | +# Grid styling |
| 81 | +p.grid.grid_line_alpha = 0.3 |
| 82 | +p.grid.grid_line_dash = "dashed" |
| 83 | + |
| 84 | +# Output |
| 85 | +export_png(p, filename="plot.png") |
| 86 | +save(p, filename="plot.html") |
0 commit comments