Skip to content

Commit 44056e6

Browse files
feat(plotnine): implement bar-basic (#132)
## Summary Implements `bar-basic` for **plotnine** library. - Uses `geom_bar` with `stat="identity"` for value-based bar heights - Includes input validation for empty data and missing columns - Configurable colors, alpha, rotation, and figure size - Subtle horizontal grid lines (alpha=0.3) on y-axis only - Y-axis starts at zero for accurate comparison **Parent Issue:** #117 **Sub-Issue:** #123 **Base Branch:** `plot/bar-basic` **Attempt:** 1/3 ## Implementation - `plots/plotnine/bar/bar-basic/default.py` ## Quality Checklist - [x] X-axis displays category labels clearly - [x] Y-axis shows numeric scale starting at zero - [x] Both axes are labeled (defaults to column names) - [x] Grid lines subtle (alpha=0.3) on y-axis only - [x] Bars have consistent width and spacing - [x] Type hints on all parameters - [x] Google-style docstring with Args, Returns, Raises, Example - [x] Input validation with clear error messages Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
1 parent 3bb19ec commit 44056e6

1 file changed

Lines changed: 102 additions & 0 deletions

File tree

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
"""
2+
bar-basic: Basic Bar Chart
3+
Library: plotnine
4+
5+
A fundamental vertical bar chart that visualizes categorical data with numeric values.
6+
"""
7+
8+
import pandas as pd
9+
from plotnine import aes, geom_bar, ggplot, labs, scale_y_continuous, theme, theme_minimal
10+
from plotnine.ggplot import ggplot as ggplot_type
11+
from plotnine.themes.elements import element_blank, element_line, element_text
12+
13+
14+
def create_plot(
15+
data: pd.DataFrame,
16+
category: str,
17+
value: str,
18+
figsize: tuple[float, float] = (10, 6),
19+
color: str = "steelblue",
20+
edgecolor: str = "black",
21+
alpha: float = 0.8,
22+
title: str | None = None,
23+
xlabel: str | None = None,
24+
ylabel: str | None = None,
25+
rotation: int = 0,
26+
**kwargs,
27+
) -> ggplot_type:
28+
"""
29+
Create a basic vertical bar chart.
30+
31+
Args:
32+
data: Input DataFrame containing the data to plot
33+
category: Column name for category labels (x-axis)
34+
value: Column name for numeric values (bar heights)
35+
figsize: Figure size as (width, height)
36+
color: Bar fill color
37+
edgecolor: Bar edge color
38+
alpha: Transparency level for bars (0-1)
39+
title: Plot title (optional)
40+
xlabel: X-axis label (defaults to column name if None)
41+
ylabel: Y-axis label (defaults to column name if None)
42+
rotation: Rotation angle for x-axis labels
43+
**kwargs: Additional parameters passed to geom_bar
44+
45+
Returns:
46+
plotnine ggplot object
47+
48+
Raises:
49+
ValueError: If data is empty
50+
KeyError: If required columns are not found in data
51+
52+
Example:
53+
>>> data = pd.DataFrame({
54+
... 'category': ['A', 'B', 'C'],
55+
... 'value': [10, 20, 15]
56+
... })
57+
>>> fig = create_plot(data, 'category', 'value', title='Sample Chart')
58+
"""
59+
# Input validation
60+
if data.empty:
61+
raise ValueError("Data cannot be empty")
62+
63+
for col in [category, value]:
64+
if col not in data.columns:
65+
available = ", ".join(data.columns)
66+
raise KeyError(f"Column '{col}' not found. Available: {available}")
67+
68+
# Set default labels to column names if not provided
69+
x_label = xlabel if xlabel is not None else category
70+
y_label = ylabel if ylabel is not None else value
71+
72+
# Create the plot
73+
plot = (
74+
ggplot(data, aes(x=category, y=value))
75+
+ geom_bar(stat="identity", fill=color, color=edgecolor, alpha=alpha, **kwargs)
76+
+ labs(x=x_label, y=y_label, title=title)
77+
+ scale_y_continuous(expand=(0, 0, 0.05, 0)) # Start y-axis at zero
78+
+ theme_minimal()
79+
+ theme(
80+
figure_size=figsize,
81+
axis_text_x=element_text(rotation=rotation, ha="right" if rotation else "center"),
82+
panel_grid_major_x=element_blank(), # Remove vertical grid lines
83+
panel_grid_minor=element_blank(), # Remove minor grid lines
84+
panel_grid_major_y=element_line(alpha=0.3), # Subtle horizontal grid
85+
)
86+
)
87+
88+
return plot
89+
90+
91+
if __name__ == "__main__":
92+
# Sample data for testing
93+
sample_data = pd.DataFrame(
94+
{"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]}
95+
)
96+
97+
# Create plot
98+
fig = create_plot(sample_data, "category", "value", title="Sales by Product")
99+
100+
# Save
101+
fig.save("plot.png", dpi=300)
102+
print("Plot saved to plot.png")

0 commit comments

Comments
 (0)