Skip to content

Commit d90d73e

Browse files
update(candlestick-basic): plotnine — comprehensive quality review
Comprehensive quality review of plotnine implementation for candlestick-basic.
1 parent f543569 commit d90d73e

2 files changed

Lines changed: 45 additions & 21 deletions

File tree

plots/candlestick-basic/implementations/plotnine.py

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
""" pyplots.ai
22
candlestick-basic: Basic Candlestick Chart
3-
Library: plotnine 0.15.2 | Python 3.13.11
4-
Quality: 91/100 | Created: 2025-12-23
3+
Library: plotnine 0.15.3 | Python 3.14.3
4+
Quality: /100 | Updated: 2026-02-24
55
"""
66

77
import numpy as np
88
import pandas as pd
99
from plotnine import (
1010
aes,
11+
coord_cartesian,
12+
element_blank,
1113
element_line,
1214
element_text,
1315
geom_rect,
1416
geom_segment,
1517
ggplot,
1618
labs,
19+
scale_color_manual,
1720
scale_fill_manual,
21+
scale_x_continuous,
22+
scale_y_continuous,
1823
theme,
1924
theme_minimal,
2025
)
@@ -32,10 +37,8 @@
3237

3338
for _ in range(n_days):
3439
open_price = price
35-
# Daily movement: random direction and magnitude
3640
change = np.random.randn() * 3
3741
close_price = open_price + change
38-
# High and low extend beyond open/close
3942
high_price = max(open_price, close_price) + abs(np.random.randn() * 1.5)
4043
low_price = min(open_price, close_price) - abs(np.random.randn() * 1.5)
4144

@@ -44,38 +47,59 @@
4447
lows.append(low_price)
4548
closes.append(close_price)
4649

47-
# Next day opens near previous close
4850
price = close_price + np.random.randn() * 0.5
4951

5052
df = pd.DataFrame({"date": dates, "open": opens, "high": highs, "low": lows, "close": closes})
5153

52-
# Add columns for plotting
53-
df["date_num"] = np.arange(len(df))
54+
# Derived columns for plotting
55+
df["day"] = np.arange(len(df))
5456
df["direction"] = np.where(df["close"] >= df["open"], "up", "down")
5557
df["body_top"] = df[["open", "close"]].max(axis=1)
5658
df["body_bottom"] = df[["open", "close"]].min(axis=1)
5759

58-
# Plot - build candlestick with segments (wicks) and rectangles (bodies)
60+
# Date labels for x-axis (show every 5th trading day)
61+
tick_indices = list(range(0, n_days, 5))
62+
tick_labels = [dates[i].strftime("%b %d") for i in tick_indices]
63+
64+
# Palette: blue for bullish, amber for bearish (colorblind-safe)
65+
palette = {"up": "#2196F3", "down": "#FF6F00"}
66+
edge_palette = {"up": "#1565C0", "down": "#E65100"}
67+
68+
# Plot - candlestick with segments (wicks) and rectangles (bodies)
5969
plot = (
6070
ggplot(df)
6171
# Wicks (high-low lines)
62-
+ geom_segment(aes(x="date_num", xend="date_num", y="low", yend="high"), color="#333333", size=1)
63-
# Candle bodies (rectangles)
72+
+ geom_segment(aes(x="day", xend="day", y="low", yend="high"), color="#555555", size=0.7)
73+
# Candle bodies with subtle edge for definition
6474
+ geom_rect(
65-
aes(xmin="date_num - 0.4", xmax="date_num + 0.4", ymin="body_bottom", ymax="body_top", fill="direction")
75+
aes(
76+
xmin="day - 0.35",
77+
xmax="day + 0.35",
78+
ymin="body_bottom",
79+
ymax="body_top",
80+
fill="direction",
81+
color="direction",
82+
),
83+
size=0.3,
6684
)
67-
# Colors: green for up, red for down
68-
+ scale_fill_manual(values={"up": "#22ab94", "down": "#f23645"}, guide=None)
69-
+ labs(x="Trading Day", y="Price ($)", title="candlestick-basic \u00b7 plotnine \u00b7 pyplots.ai")
85+
+ scale_fill_manual(values=palette, guide=None)
86+
+ scale_color_manual(values=edge_palette, guide=None)
87+
# Date labels on x-axis
88+
+ scale_x_continuous(breaks=tick_indices, labels=tick_labels, expand=(0.02, 0.5))
89+
+ scale_y_continuous(labels=lambda vals: [f"${v:,.0f}" for v in vals])
90+
+ coord_cartesian(ylim=(df["low"].min() - 1.5, df["high"].max() + 1.5))
91+
+ labs(x="", y="Price ($)", title="candlestick-basic · plotnine · pyplots.ai")
7092
+ theme_minimal()
7193
+ theme(
7294
figure_size=(16, 9),
7395
text=element_text(size=14),
7496
axis_title=element_text(size=20),
7597
axis_text=element_text(size=16),
7698
plot_title=element_text(size=24),
77-
panel_grid_major=element_line(color="#cccccc", size=0.5, alpha=0.3),
78-
panel_grid_minor=element_line(color="#eeeeee", size=0.3, alpha=0.2),
99+
panel_grid_major_x=element_blank(),
100+
panel_grid_minor_x=element_blank(),
101+
panel_grid_major_y=element_line(color="#d0d0d0", size=0.4, alpha=0.4),
102+
panel_grid_minor_y=element_blank(),
79103
)
80104
)
81105

plots/candlestick-basic/metadata/plotnine.yaml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
library: plotnine
22
specification_id: candlestick-basic
33
created: '2025-12-23T10:01:36Z'
4-
updated: '2025-12-23T10:08:06Z'
5-
generated_by: claude-opus-4-5-20251101
4+
updated: '2026-02-24T20:50:21+00:00'
5+
generated_by: claude-opus-4-6
66
workflow_run: 20457533627
77
issue: 0
8-
python_version: 3.13.11
9-
library_version: 0.15.2
8+
python_version: "3.14.3"
9+
library_version: "0.15.3"
1010
preview_url: https://storage.googleapis.com/pyplots-images/plots/candlestick-basic/plotnine/plot.png
1111
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/candlestick-basic/plotnine/plot_thumb.png
1212
preview_html: null
13-
quality_score: 91
13+
quality_score: null
1414
impl_tags:
1515
dependencies: []
1616
techniques:

0 commit comments

Comments
 (0)