Skip to content

Commit 86399bd

Browse files
feat(letsplot): implement line-basic
Refactored to follow KISS style guidelines: - Simple sequential script (no functions or classes) - Uses example data from spec - Proper 4800x2700 px output with scale=3 - Python Blue (#306998) color from style guide
1 parent 27357ca commit 86399bd

1 file changed

Lines changed: 22 additions & 142 deletions

File tree

Lines changed: 22 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
"""
2-
line-basic: Basic Line Chart
3-
Library: lets-plot
4-
5-
A fundamental line chart that visualizes trends and patterns in data over a continuous axis.
2+
line-basic: Basic Line Plot
3+
Library: letsplot
64
"""
75

86
import pandas as pd
@@ -20,147 +18,29 @@
2018
theme,
2119
theme_minimal,
2220
)
23-
from lets_plot.plot.core import PlotSpec
2421

2522

2623
LetsPlot.setup_html()
2724

28-
29-
def create_plot(
30-
data: pd.DataFrame,
31-
x: str,
32-
y: str,
33-
figsize: tuple[float, float] = (10, 6),
34-
linewidth: float = 2.0,
35-
color: str = "#306998",
36-
alpha: float = 1.0,
37-
marker: str | None = None,
38-
marker_size: float = 6.0,
39-
title: str | None = None,
40-
xlabel: str | None = None,
41-
ylabel: str | None = None,
42-
linestyle: str = "solid",
43-
grid: bool = True,
44-
**kwargs,
45-
) -> PlotSpec:
46-
"""
47-
Create a basic line chart connecting data points in sequence.
48-
49-
Args:
50-
data: Input DataFrame containing the data to plot
51-
x: Column name for x-axis values (typically numeric or ordered)
52-
y: Column name for y-axis values (numeric)
53-
figsize: Figure size as (width, height) in inches (used for aspect ratio)
54-
linewidth: Width of the line in points
55-
color: Line color (default: Python Blue from style guide)
56-
alpha: Line transparency (0.0 to 1.0)
57-
marker: Marker style for data points (e.g., 'o', 's', '^')
58-
marker_size: Size of markers if enabled
59-
title: Plot title (optional)
60-
xlabel: X-axis label (defaults to column name if None)
61-
ylabel: Y-axis label (defaults to column name if None)
62-
linestyle: Line style ('solid', 'dashed', 'dotted', 'dotdash')
63-
grid: Whether to show grid lines
64-
**kwargs: Additional parameters
65-
66-
Returns:
67-
lets-plot PlotSpec object
68-
69-
Raises:
70-
ValueError: If data is empty
71-
KeyError: If required columns are not found in data
72-
73-
Example:
74-
>>> data = pd.DataFrame({
75-
... 'month': [1, 2, 3, 4, 5, 6],
76-
... 'sales': [100, 150, 130, 180, 200, 190]
77-
... })
78-
>>> fig = create_plot(data, 'month', 'sales')
79-
"""
80-
# Input validation
81-
if data.empty:
82-
raise ValueError("Data cannot be empty")
83-
84-
for col in [x, y]:
85-
if col not in data.columns:
86-
available = ", ".join(data.columns)
87-
raise KeyError(f"Column '{col}' not found. Available: {available}")
88-
89-
# Set default labels to column names if not provided
90-
x_label = xlabel if xlabel is not None else x
91-
y_label = ylabel if ylabel is not None else y
92-
93-
# Sort data by x to ensure proper line connection
94-
plot_data = data.sort_values(by=x).copy()
95-
96-
# Map linestyle aliases to lets-plot format
97-
linetype_map = {
98-
"-": "solid",
99-
"--": "dashed",
100-
"-.": "dotdash",
101-
":": "dotted",
102-
"solid": "solid",
103-
"dashed": "dashed",
104-
"dotted": "dotted",
105-
"dotdash": "dotdash",
106-
}
107-
linetype = linetype_map.get(linestyle, "solid")
108-
109-
# Create the base plot with line geometry
110-
plot = (
111-
ggplot(plot_data, aes(x=x, y=y))
112-
+ geom_line(color=color, size=linewidth, alpha=alpha, linetype=linetype)
113-
+ labs(x=x_label, y=y_label, title=title)
114-
+ theme_minimal()
115-
+ theme(
116-
plot_title=element_text(size=20, face="bold"),
117-
axis_title=element_text(size=20),
118-
axis_text=element_text(size=16),
119-
legend_text=element_text(size=16),
120-
panel_grid_major=element_line(color="#CCCCCC", size=0.5) if grid else element_line(color="rgba(0,0,0,0)"),
121-
panel_grid_minor=element_line(color="#EEEEEE", size=0.3) if grid else element_line(color="rgba(0,0,0,0)"),
122-
)
123-
+ ggsize(1600, 900) # Base size, scaled 3x on export to get 4800 x 2700
124-
)
125-
126-
# Add markers if specified
127-
if marker is not None:
128-
# Map common marker styles to lets-plot shapes
129-
marker_map = {
130-
"o": 16, # circle
131-
"s": 15, # square
132-
"^": 17, # triangle up
133-
"v": 25, # triangle down
134-
"D": 18, # diamond
135-
"*": 8, # asterisk
136-
}
137-
shape = marker_map.get(marker, 16)
138-
plot = plot + geom_point(color=color, size=marker_size, alpha=alpha, shape=shape)
139-
140-
return plot
141-
142-
143-
if __name__ == "__main__":
144-
# Sample data for testing
145-
sample_data = pd.DataFrame(
146-
{
147-
"month": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
148-
"sales": [120, 150, 170, 160, 190, 220, 240, 230, 210, 195, 180, 210],
149-
}
150-
)
151-
152-
# Create plot with markers
153-
fig = create_plot(
154-
sample_data,
155-
"month",
156-
"sales",
157-
title="Monthly Sales Trend",
158-
xlabel="Month",
159-
ylabel="Sales ($K)",
160-
marker="o",
161-
linewidth=2.5,
25+
# Data
26+
data = pd.DataFrame({"time": [1, 2, 3, 4, 5, 6, 7], "value": [10, 15, 13, 18, 22, 19, 25]})
27+
28+
# Plot
29+
plot = (
30+
ggplot(data, aes(x="time", y="value"))
31+
+ geom_line(color="#306998", size=2, alpha=1.0)
32+
+ geom_point(color="#306998", size=4, alpha=1.0)
33+
+ labs(x="Time", y="Value", title="Basic Line Plot")
34+
+ theme_minimal()
35+
+ theme(
36+
plot_title=element_text(size=20, face="bold"),
37+
axis_title=element_text(size=20),
38+
axis_text=element_text(size=16),
39+
panel_grid_major=element_line(color="#CCCCCC", size=0.5),
40+
panel_grid_minor=element_line(color="#EEEEEE", size=0.3),
16241
)
42+
+ ggsize(1600, 900)
43+
)
16344

164-
# Save - scale 3x to get 4800 x 2700 px
165-
ggsave(fig, "plot.png", path=".", scale=3)
166-
print("Plot saved to plot.png")
45+
# Save - scale 3x to get 4800 x 2700 px
46+
ggsave(plot, "plot.png", path=".", scale=3)

0 commit comments

Comments
 (0)