Skip to content

Commit 2dad82e

Browse files
feat(altair): implement bar-basic (#129)
## Summary Implements `bar-basic` for **altair** library. - Basic vertical bar chart for categorical data - Y-axis starts at zero for accurate comparison - Subtle grid lines (gridOpacity=0.3) on y-axis - Configurable color, transparency, and label rotation - Tooltips for interactive exploration - Full input validation with clear error messages **Parent Issue:** #117 **Sub-Issue:** #122 **Base Branch:** `plot/bar-basic` **Attempt:** 1/3 ## Implementation - `plots/altair/bar/bar-basic/default.py` Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
1 parent ae66ffc commit 2dad82e

1 file changed

Lines changed: 107 additions & 0 deletions

File tree

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
"""
2+
bar-basic: Basic Bar Chart
3+
Library: altair
4+
"""
5+
6+
import altair as alt
7+
import pandas as pd
8+
9+
10+
def create_plot(
11+
data: pd.DataFrame,
12+
category: str,
13+
value: str,
14+
*,
15+
color: str = "steelblue",
16+
alpha: float = 0.8,
17+
title: str | None = None,
18+
xlabel: str | None = None,
19+
ylabel: str | None = None,
20+
rotation: int = 0,
21+
**kwargs,
22+
) -> alt.Chart:
23+
"""
24+
Create a basic vertical bar chart.
25+
26+
A fundamental bar chart that visualizes categorical data with numeric values,
27+
ideal for comparing quantities across discrete categories.
28+
29+
Args:
30+
data: Input DataFrame containing the data to plot.
31+
category: Column name for categorical x-axis values.
32+
value: Column name for numeric y-axis values.
33+
color: Bar fill color. Defaults to "steelblue".
34+
alpha: Transparency level for bars (0-1). Defaults to 0.8.
35+
title: Plot title. Defaults to None.
36+
xlabel: X-axis label. Defaults to column name if None.
37+
ylabel: Y-axis label. Defaults to column name if None.
38+
rotation: Rotation angle for x-axis labels. Defaults to 0.
39+
**kwargs: Additional parameters passed to chart properties.
40+
41+
Returns:
42+
Altair Chart object.
43+
44+
Raises:
45+
ValueError: If data is empty.
46+
KeyError: If required columns are not found in data.
47+
48+
Example:
49+
>>> data = pd.DataFrame({
50+
... 'category': ['A', 'B', 'C'],
51+
... 'value': [10, 20, 15]
52+
... })
53+
>>> chart = create_plot(data, 'category', 'value', title='Example')
54+
"""
55+
# Input validation
56+
if data.empty:
57+
raise ValueError("Data cannot be empty")
58+
59+
for col in [category, value]:
60+
if col not in data.columns:
61+
available = ", ".join(data.columns)
62+
raise KeyError(f"Column '{col}' not found. Available: {available}")
63+
64+
# Determine axis labels
65+
x_label = xlabel if xlabel is not None else category
66+
y_label = ylabel if ylabel is not None else value
67+
68+
# Build x-axis configuration
69+
x_axis = alt.Axis(title=x_label, labelAngle=-rotation if rotation != 0 else 0)
70+
71+
# Build y-axis configuration with subtle grid
72+
y_axis = alt.Axis(title=y_label, grid=True, gridOpacity=0.3)
73+
74+
# Create the bar chart
75+
chart = (
76+
alt.Chart(data)
77+
.mark_bar(color=color, opacity=alpha)
78+
.encode(
79+
x=alt.X(f"{category}:N", axis=x_axis, sort=None),
80+
y=alt.Y(f"{value}:Q", axis=y_axis, scale=alt.Scale(domain=[0, data[value].max() * 1.1])),
81+
tooltip=[alt.Tooltip(f"{category}:N", title=x_label), alt.Tooltip(f"{value}:Q", title=y_label)],
82+
)
83+
.properties(width=800, height=450)
84+
)
85+
86+
# Add title if provided
87+
if title is not None:
88+
chart = chart.properties(title=title)
89+
90+
# Configure chart appearance
91+
chart = chart.configure_axis(labelFontSize=12, titleFontSize=14).configure_title(fontSize=16, anchor="middle")
92+
93+
return chart
94+
95+
96+
if __name__ == "__main__":
97+
# Sample data for testing
98+
sample_data = pd.DataFrame(
99+
{"category": ["Product A", "Product B", "Product C", "Product D", "Product E"], "value": [45, 78, 52, 91, 63]}
100+
)
101+
102+
# Create plot
103+
fig = create_plot(sample_data, "category", "value", title="Sales by Product")
104+
105+
# Save
106+
fig.save("plot.png", scale_factor=2.0)
107+
print("Plot saved to plot.png")

0 commit comments

Comments
 (0)