Skip to content

Commit 8637d79

Browse files
Merge branch 'main' into implementation/bar-basic/plotly
2 parents d076232 + 54028d2 commit 8637d79

24 files changed

Lines changed: 2322 additions & 1240 deletions

plots/bar-basic/implementations/altair.py

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,74 @@
11
""" pyplots.ai
22
bar-basic: Basic Bar Chart
3-
Library: altair 6.0.0 | Python 3.13.11
4-
Quality: 93/100 | Created: 2025-12-23
3+
Library: altair 6.0.0 | Python 3.14
4+
Quality: 92/100 | Created: 2025-12-23
55
"""
66

77
import altair as alt
88
import pandas as pd
99

1010

1111
# Data - Product sales by category (realistic retail scenario)
12+
# Includes close-valued pairs (Clothing/Home & Garden, Toys/Food) to showcase comparison
1213
data = pd.DataFrame(
1314
{
1415
"category": ["Electronics", "Clothing", "Home & Garden", "Sports", "Books", "Toys", "Food"],
15-
"value": [45200, 32100, 28400, 21800, 18500, 15200, 12300],
16+
"value": [45200, 31500, 29800, 21800, 18500, 14200, 13100],
1617
}
1718
)
1819

19-
# Chart
20-
chart = (
20+
# Highlight the top-performing category
21+
data["is_top"] = data["value"] == data["value"].max()
22+
23+
# Sort order by descending value
24+
sort_order = data.sort_values("value", ascending=False)["category"].tolist()
25+
26+
# Chart - bars with conditional color to highlight leader
27+
bars = (
2128
alt.Chart(data)
22-
.mark_bar(color="#306998", cornerRadiusTopLeft=4, cornerRadiusTopRight=4)
29+
.mark_bar(cornerRadiusTopLeft=4, cornerRadiusTopRight=4)
2330
.encode(
2431
x=alt.X(
2532
"category:N",
2633
title="Product Category",
27-
sort="-y",
34+
sort=sort_order,
2835
axis=alt.Axis(labelAngle=-45, labelFontSize=18, titleFontSize=22),
2936
),
30-
y=alt.Y("value:Q", title="Sales ($)", axis=alt.Axis(labelFontSize=18, titleFontSize=22, format="$,.0f")),
37+
y=alt.Y(
38+
"value:Q",
39+
title="Sales ($)",
40+
scale=alt.Scale(domain=[0, 50000]),
41+
axis=alt.Axis(
42+
labelFontSize=18, titleFontSize=22, format="$,.0f", values=[0, 10000, 20000, 30000, 40000, 50000]
43+
),
44+
),
45+
color=alt.condition(alt.datum.is_top, alt.value("#FFD43B"), alt.value("#306998")),
3146
tooltip=[alt.Tooltip("category:N", title="Category"), alt.Tooltip("value:Q", title="Sales", format="$,.0f")],
3247
)
33-
.properties(width=1500, height=800, title=alt.Title(text="bar-basic · altair · pyplots.ai", fontSize=28))
48+
)
49+
50+
# Value labels above bars
51+
labels = bars.mark_text(align="center", baseline="bottom", dy=-8, fontSize=16, color="#333333").encode(
52+
text=alt.Text("value:Q", format="$,.0f"), color=alt.value("#333333")
53+
)
54+
55+
# Annotation highlighting top performer
56+
annotation = (
57+
alt.Chart(pd.DataFrame({"category": ["Electronics"], "value": [45200], "label": ["Top seller — $45.2k"]}))
58+
.mark_text(align="center", baseline="bottom", dy=-28, fontSize=18, fontWeight="bold", color="#b8860b")
59+
.encode(x=alt.X("category:N", sort=sort_order), y=alt.Y("value:Q"), text=alt.Text("label:N"))
60+
)
61+
62+
# Combine bars + labels + annotation
63+
chart = (
64+
(bars + labels + annotation)
65+
.properties(width=1600, height=900, title=alt.Title(text="bar-basic · altair · pyplots.ai", fontSize=28))
3466
.configure_view(strokeWidth=0)
35-
.configure_axis(grid=True, gridOpacity=0.3, gridDash=[4, 4])
67+
.configure_axis(grid=False)
68+
.configure_axisY(grid=True, gridOpacity=0.15, gridDash=[4, 4])
3669
)
3770

38-
# Save as PNG (scale_factor=3 gives 4500x2400, close to target 4800x2700)
71+
# Save as PNG (scale_factor=3 gives 4800x2700 at 1600x900)
3972
chart.save("plot.png", scale_factor=3.0)
4073

4174
# Save interactive HTML

plots/bar-basic/implementations/bokeh.py

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,88 @@
11
""" pyplots.ai
22
bar-basic: Basic Bar Chart
3-
Library: bokeh 3.8.1 | Python 3.13.11
4-
Quality: 92/100 | Created: 2025-12-23
3+
Library: bokeh 3.8.2 | Python 3.14
4+
Quality: 90/100 | Created: 2025-12-23
55
"""
66

77
from bokeh.io import export_png
8-
from bokeh.models import ColumnDataSource, LabelSet
8+
from bokeh.models import ColumnDataSource, LabelSet, NumeralTickFormatter
99
from bokeh.plotting import figure, output_file, save
1010

1111

12-
# Data - Product sales by category
13-
categories = ["Electronics", "Clothing", "Home & Garden", "Sports", "Books", "Toys"]
14-
values = [42500, 31200, 28700, 19800, 15400, 12600]
12+
# Data - Quarterly revenue by department (varied, non-monotonic pattern)
13+
categories = ["Engineering", "Marketing", "Sales", "Support", "Design", "Operations"]
14+
values = [38200, 21500, 45800, 14300, 27600, 19100]
15+
labels = [f"${v / 1000:.1f}K" for v in values]
1516

1617
# Create ColumnDataSource
17-
source = ColumnDataSource(data={"categories": categories, "values": values})
18+
source = ColumnDataSource(data={"categories": categories, "values": values, "labels": labels})
1819

19-
# Create figure with categorical x-axis (4800 × 2700 px)
20+
# Create figure with categorical x-axis (4800 x 2700 px)
2021
p = figure(
2122
x_range=categories,
2223
width=4800,
2324
height=2700,
24-
title="bar-basic · bokeh · pyplots.ai",
25-
x_axis_label="Product Category",
26-
y_axis_label="Sales ($)",
25+
title="bar-basic \u00b7 bokeh \u00b7 pyplots.ai",
26+
x_axis_label="Department",
27+
y_axis_label="Revenue ($)",
2728
toolbar_location=None,
2829
)
2930

30-
# Create bars
31-
p.vbar(x="categories", top="values", source=source, width=0.7, color="#306998", alpha=0.9)
31+
# Create bars with white edge for definition
32+
p.vbar(
33+
x="categories", top="values", source=source, width=0.7, color="#306998", alpha=0.9, line_color="white", line_width=2
34+
)
3235

33-
# Add value labels on top of bars
34-
labels = LabelSet(
36+
# Add formatted value labels above bars
37+
labels_glyph = LabelSet(
3538
x="categories",
3639
y="values",
37-
text="values",
40+
text="labels",
3841
level="glyph",
39-
x_offset=-25,
40-
y_offset=5,
42+
x_offset=0,
43+
y_offset=8,
4144
source=source,
4245
text_font_size="28pt",
4346
text_color="#333333",
47+
text_align="center",
4448
)
45-
p.add_layout(labels)
49+
p.add_layout(labels_glyph)
4650

47-
# Styling for 4800×2700 px
51+
# Styling for 4800x2700 px
4852
p.title.text_font_size = "36pt"
4953
p.title.align = "center"
5054
p.xaxis.axis_label_text_font_size = "28pt"
5155
p.yaxis.axis_label_text_font_size = "28pt"
5256
p.xaxis.major_label_text_font_size = "24pt"
5357
p.yaxis.major_label_text_font_size = "24pt"
5458

55-
# Grid styling
59+
# Clean L-shaped frame: remove top and right spines
60+
p.outline_line_color = None
61+
p.xaxis.axis_line_color = "#333333"
62+
p.yaxis.axis_line_color = "#333333"
63+
p.xaxis.axis_line_width = 2
64+
p.yaxis.axis_line_width = 2
65+
66+
# Remove tick marks, keep labels
67+
p.xaxis.major_tick_line_color = None
68+
p.yaxis.major_tick_line_color = None
69+
p.xaxis.minor_tick_line_color = None
70+
p.yaxis.minor_tick_line_color = None
71+
72+
# Grid styling - y-axis only, subtle solid lines
5673
p.xgrid.grid_line_color = None
57-
p.ygrid.grid_line_alpha = 0.3
58-
p.ygrid.grid_line_dash = "dashed"
74+
p.ygrid.grid_line_alpha = 0.2
75+
p.ygrid.grid_line_dash = "solid"
5976

60-
# Y-axis starts at 0
77+
# Format y-axis with dollar amounts
78+
p.yaxis.formatter = NumeralTickFormatter(format="$0,0")
79+
80+
# Y-axis starts at 0, add headroom for labels
6181
p.y_range.start = 0
82+
p.y_range.end = max(values) * 1.15
83+
84+
# Background
85+
p.background_fill_color = "#FFFFFF"
6286

6387
# Save as PNG
6488
export_png(p, filename="plot.png")

0 commit comments

Comments
 (0)