|
1 | 1 | """ |
2 | 2 | area-basic: Basic Area Chart |
3 | | -Implementation for: matplotlib |
4 | | -Variant: default |
5 | | -Python: 3.10+ |
| 3 | +Library: matplotlib |
6 | 4 | """ |
7 | 5 |
|
8 | | -from typing import TYPE_CHECKING, Optional |
9 | | - |
10 | 6 | import matplotlib.pyplot as plt |
11 | 7 | import pandas as pd |
12 | 8 |
|
13 | 9 |
|
14 | | -if TYPE_CHECKING: |
15 | | - from matplotlib.figure import Figure |
16 | | - |
17 | | - |
18 | | -def create_plot( |
19 | | - data: pd.DataFrame, |
20 | | - x: str, |
21 | | - y: str, |
22 | | - color: str = "steelblue", |
23 | | - alpha: float = 0.4, |
24 | | - line_color: Optional[str] = None, |
25 | | - line_width: float = 2.0, |
26 | | - title: Optional[str] = None, |
27 | | - xlabel: Optional[str] = None, |
28 | | - ylabel: Optional[str] = None, |
29 | | - figsize: tuple[float, float] = (16, 9), |
30 | | - **kwargs, |
31 | | -) -> "Figure": |
32 | | - """ |
33 | | - Create a basic area chart showing a filled region between the x-axis and a line. |
34 | | -
|
35 | | - Args: |
36 | | - data: Input DataFrame with required columns |
37 | | - x: Column name for x-axis values (continuous sequence) |
38 | | - y: Column name for y-axis values (numeric values) |
39 | | - color: Fill color for the area (default: "steelblue") |
40 | | - alpha: Transparency level for the filled area 0.0-1.0 (default: 0.4) |
41 | | - line_color: Color of the top edge line (default: same as fill color) |
42 | | - line_width: Width of the top edge line (default: 2.0) |
43 | | - title: Plot title (default: None) |
44 | | - xlabel: Custom x-axis label (default: column name) |
45 | | - ylabel: Custom y-axis label (default: column name) |
46 | | - figsize: Figure size as (width, height) (default: (16, 9)) |
47 | | - **kwargs: Additional parameters passed to ax.fill_between() |
48 | | -
|
49 | | - Returns: |
50 | | - Matplotlib Figure object |
51 | | -
|
52 | | - Raises: |
53 | | - ValueError: If data is empty |
54 | | - KeyError: If required columns not found |
55 | | -
|
56 | | - Example: |
57 | | - >>> data = pd.DataFrame({'Time': [1, 2, 3, 4, 5], 'Value': [10, 25, 15, 30, 20]}) |
58 | | - >>> fig = create_plot(data, x='Time', y='Value') |
59 | | - """ |
60 | | - # Input validation |
61 | | - if data.empty: |
62 | | - raise ValueError("Data cannot be empty") |
63 | | - |
64 | | - # Check required columns |
65 | | - for col in [x, y]: |
66 | | - if col not in data.columns: |
67 | | - available = ", ".join(data.columns) |
68 | | - raise KeyError(f"Column '{col}' not found. Available: {available}") |
69 | | - |
70 | | - # Create figure |
71 | | - fig, ax = plt.subplots(figsize=figsize) |
72 | | - |
73 | | - # Get data values |
74 | | - x_values = data[x] |
75 | | - y_values = data[y] |
76 | | - |
77 | | - # Determine line color (default to fill color if not specified) |
78 | | - edge_color = line_color if line_color else color |
79 | | - |
80 | | - # Plot the filled area |
81 | | - ax.fill_between(x_values, y_values, alpha=alpha, color=color, **kwargs) |
82 | | - |
83 | | - # Plot the top edge line for clarity |
84 | | - ax.plot(x_values, y_values, color=edge_color, linewidth=line_width) |
85 | | - |
86 | | - # Apply styling |
87 | | - ax.set_xlabel(xlabel or x) |
88 | | - ax.set_ylabel(ylabel or y) |
89 | | - ax.grid(True, alpha=0.3, linestyle="--") |
90 | | - |
91 | | - # Title |
92 | | - if title: |
93 | | - ax.set_title(title, fontsize=14, fontweight="bold") |
94 | | - |
95 | | - # Tight layout to avoid label clipping |
96 | | - plt.tight_layout() |
97 | | - |
98 | | - return fig |
| 10 | +# Data - Monthly sales from spec |
| 11 | +data = pd.DataFrame( |
| 12 | + { |
| 13 | + "month": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], |
| 14 | + "sales": [120, 135, 148, 162, 175, 195, 210, 198, 185, 170, 158, 190], |
| 15 | + } |
| 16 | +) |
99 | 17 |
|
| 18 | +# Create plot |
| 19 | +fig, ax = plt.subplots(figsize=(16, 9)) |
100 | 20 |
|
101 | | -if __name__ == "__main__": |
102 | | - # Sample data for testing - simulating monthly website traffic |
103 | | - data = pd.DataFrame( |
104 | | - { |
105 | | - "Month": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], |
106 | | - "Visitors": [12000, 15000, 18000, 22000, 25000, 28000, 32000, 30000, 27000, 24000, 20000, 18000], |
107 | | - } |
108 | | - ) |
| 21 | +# Plot area chart - use numeric x-axis for proper fill_between |
| 22 | +x = range(len(data)) |
| 23 | +ax.fill_between(x, data["sales"], alpha=0.5, color="#306998") |
| 24 | +ax.plot(x, data["sales"], color="#306998", linewidth=2) |
109 | 25 |
|
110 | | - # For a proper area chart, we need numeric x values |
111 | | - # Convert month names to numeric positions for continuous x-axis |
112 | | - data["Month_Num"] = range(1, 13) |
| 26 | +# Set x-tick labels to month names |
| 27 | +ax.set_xticks(x) |
| 28 | +ax.set_xticklabels(data["month"]) |
113 | 29 |
|
114 | | - # Create plot |
115 | | - fig = create_plot( |
116 | | - data, x="Month_Num", y="Visitors", title="Monthly Website Traffic", xlabel="Month", ylabel="Number of Visitors" |
117 | | - ) |
| 30 | +# Labels and styling |
| 31 | +ax.set_xlabel("Month", fontsize=20) |
| 32 | +ax.set_ylabel("Sales", fontsize=20) |
| 33 | +ax.set_title("Monthly Sales Volume", fontsize=20) |
| 34 | +ax.tick_params(axis="both", labelsize=16) |
| 35 | +ax.grid(True, alpha=0.3, linestyle="--") |
118 | 36 |
|
119 | | - # Customize x-ticks to show month names |
120 | | - ax = fig.axes[0] |
121 | | - ax.set_xticks(range(1, 13)) |
122 | | - ax.set_xticklabels(data["Month"]) |
| 37 | +# Set y-axis to start from 0 for proper area representation |
| 38 | +ax.set_ylim(bottom=0) |
123 | 39 |
|
124 | | - # Save for inspection |
125 | | - plt.savefig("plot.png", dpi=300, bbox_inches="tight") |
126 | | - print("Plot saved to plot.png") |
| 40 | +plt.tight_layout() |
| 41 | +plt.savefig("plot.png", dpi=300, bbox_inches="tight") |
0 commit comments