Skip to content

Commit bdeeb33

Browse files
feat(bokeh): implement bar-basic
Simplified implementation following KISS principles: - Sequential script structure without functions/classes - 4800x2700px output with proper typography sizing - Uses ColumnDataSource and vbar glyph method - Python Blue (#306998) color from style guide
1 parent 27357ca commit bdeeb33

1 file changed

Lines changed: 33 additions & 141 deletions

File tree

plots/bokeh/vbar/bar-basic/default.py

Lines changed: 33 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -3,150 +3,42 @@
33
Library: bokeh
44
"""
55

6-
from typing import TYPE_CHECKING
7-
86
import pandas as pd
97
from bokeh.io import export_png
108
from bokeh.models import ColumnDataSource
119
from bokeh.plotting import figure
1210

1311

14-
if TYPE_CHECKING:
15-
from bokeh.plotting import figure as Figure
16-
17-
18-
def create_plot(
19-
data: pd.DataFrame,
20-
category: str,
21-
value: str,
22-
figsize: tuple[int, int] = (1600, 900),
23-
color: str = "steelblue",
24-
edgecolor: str = "black",
25-
alpha: float = 0.8,
26-
title: str | None = None,
27-
xlabel: str | None = None,
28-
ylabel: str | None = None,
29-
rotation: int = 0,
30-
**kwargs,
31-
) -> "Figure":
32-
"""
33-
Create a basic vertical bar chart.
34-
35-
A fundamental bar chart that visualizes categorical data with numeric values,
36-
ideal for comparing quantities across discrete categories.
37-
38-
Args:
39-
data: Input DataFrame with categorical and numeric columns
40-
category: Column name for category labels (x-axis)
41-
value: Column name for numeric values (bar heights)
42-
figsize: Figure size as (width, height) in pixels. Defaults to (1600, 900).
43-
color: Bar fill color. Defaults to "steelblue".
44-
edgecolor: Bar edge color. Defaults to "black".
45-
alpha: Transparency level for bars (0-1). Defaults to 0.8.
46-
title: Plot title. Defaults to None.
47-
xlabel: X-axis label. Defaults to category column name.
48-
ylabel: Y-axis label. Defaults to value column name.
49-
rotation: Rotation angle for x-axis labels in degrees. Defaults to 0.
50-
**kwargs: Additional parameters passed to figure.
51-
52-
Returns:
53-
Bokeh figure object with the bar chart.
54-
55-
Raises:
56-
ValueError: If data is empty.
57-
KeyError: If required columns are not found in data.
58-
59-
Example:
60-
>>> data = pd.DataFrame({
61-
... 'category': ['A', 'B', 'C', 'D'],
62-
... 'value': [10, 25, 15, 30]
63-
... })
64-
>>> fig = create_plot(data, 'category', 'value', title='Sample Bar Chart')
65-
"""
66-
# Input validation
67-
if data.empty:
68-
raise ValueError("Data cannot be empty")
69-
70-
for col in [category, value]:
71-
if col not in data.columns:
72-
available = ", ".join(data.columns.tolist())
73-
raise KeyError(f"Column '{col}' not found. Available: {available}")
74-
75-
# Prepare data - drop NaN values
76-
plot_data = data[[category, value]].dropna()
77-
78-
# Get categories as list for x_range
79-
categories = plot_data[category].astype(str).tolist()
80-
81-
# Create ColumnDataSource
82-
source = ColumnDataSource(data={"categories": categories, "values": plot_data[value].tolist()})
83-
84-
# Set labels
85-
x_label = xlabel if xlabel is not None else category
86-
y_label = ylabel if ylabel is not None else value
87-
88-
# Create figure with categorical x-axis
89-
p = figure(
90-
width=figsize[0],
91-
height=figsize[1],
92-
x_range=categories,
93-
title=title,
94-
x_axis_label=x_label,
95-
y_axis_label=y_label,
96-
**kwargs,
97-
)
98-
99-
# Calculate bar width (0.8 of available space)
100-
bar_width = 0.8
101-
102-
# Add bars
103-
p.vbar(
104-
x="categories",
105-
top="values",
106-
width=bar_width,
107-
source=source,
108-
fill_color=color,
109-
fill_alpha=alpha,
110-
line_color=edgecolor,
111-
line_width=1,
112-
)
113-
114-
# Ensure y-axis starts at zero
115-
p.y_range.start = 0
116-
117-
# Style grid - subtle y-grid only
118-
p.xgrid.grid_line_color = None
119-
p.ygrid.grid_line_alpha = 0.3
120-
121-
# Apply x-axis label rotation if specified
122-
if rotation != 0:
123-
from math import pi
124-
125-
p.xaxis.major_label_orientation = rotation * pi / 180
126-
127-
# Style axis labels
128-
p.xaxis.axis_label_text_font_size = "12pt"
129-
p.yaxis.axis_label_text_font_size = "12pt"
130-
p.xaxis.major_label_text_font_size = "10pt"
131-
p.yaxis.major_label_text_font_size = "10pt"
132-
133-
# Style title if present
134-
if title:
135-
p.title.text_font_size = "14pt"
136-
p.title.align = "center"
137-
138-
return p
139-
140-
141-
if __name__ == "__main__":
142-
# Sample data for testing
143-
sample_data = pd.DataFrame(
144-
{"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]}
145-
)
146-
147-
# Create plot
148-
fig = create_plot(sample_data, "category", "value", title="Sales by Product", xlabel="Product", ylabel="Sales ($)")
149-
150-
# Save
151-
export_png(fig, filename="plot.png")
152-
print("Plot saved to plot.png")
12+
# Data
13+
data = pd.DataFrame(
14+
{"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]}
15+
)
16+
17+
# Create ColumnDataSource
18+
source = ColumnDataSource(data)
19+
20+
# Create figure with categorical x-axis
21+
p = figure(
22+
width=4800,
23+
height=2700,
24+
x_range=data["category"].tolist(),
25+
title="Basic Bar Chart",
26+
x_axis_label="Category",
27+
y_axis_label="Value",
28+
)
29+
30+
# Plot vertical bars
31+
p.vbar(x="category", top="value", source=source, width=0.7, color="#306998", alpha=0.8)
32+
33+
# Styling
34+
p.title.text_font_size = "20pt"
35+
p.xaxis.axis_label_text_font_size = "20pt"
36+
p.yaxis.axis_label_text_font_size = "20pt"
37+
p.xaxis.major_label_text_font_size = "16pt"
38+
p.yaxis.major_label_text_font_size = "16pt"
39+
p.xgrid.grid_line_color = None
40+
p.ygrid.grid_line_alpha = 0.3
41+
p.y_range.start = 0
42+
43+
# Save
44+
export_png(p, filename="plot.png")

0 commit comments

Comments
 (0)