|
1 | 1 | """ |
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 |
6 | 4 | """ |
7 | 5 |
|
8 | 6 | import pandas as pd |
|
20 | 18 | theme, |
21 | 19 | theme_minimal, |
22 | 20 | ) |
23 | | -from lets_plot.plot.core import PlotSpec |
24 | 21 |
|
25 | 22 |
|
26 | 23 | LetsPlot.setup_html() |
27 | 24 |
|
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), |
162 | 41 | ) |
| 42 | + + ggsize(1600, 900) |
| 43 | +) |
163 | 44 |
|
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