|
| 1 | +""" pyplots.ai |
| 2 | +line-realtime: Real-Time Updating Line Chart |
| 3 | +Library: matplotlib 3.10.8 | Python 3.13.11 |
| 4 | +Quality: 92/100 | Created: 2025-12-31 |
| 5 | +""" |
| 6 | + |
| 7 | +import matplotlib.pyplot as plt |
| 8 | +import numpy as np |
| 9 | +from matplotlib.patches import FancyArrowPatch |
| 10 | + |
| 11 | + |
| 12 | +# Data - Simulated CPU usage monitoring with sliding window |
| 13 | +np.random.seed(42) |
| 14 | +n_points = 100 |
| 15 | +visible_points = 60 |
| 16 | + |
| 17 | +# Generate realistic CPU usage pattern (0-100%) |
| 18 | +base_usage = 45 + 15 * np.sin(np.linspace(0, 4 * np.pi, n_points)) |
| 19 | +noise = np.random.normal(0, 5, n_points) |
| 20 | +spikes = np.zeros(n_points) |
| 21 | +spike_indices = [15, 35, 55, 78] |
| 22 | +for idx in spike_indices: |
| 23 | + spikes[idx : idx + 3] = np.array([20, 15, 8])[: min(3, n_points - idx)] |
| 24 | + |
| 25 | +cpu_usage = np.clip(base_usage + noise + spikes, 0, 100) |
| 26 | + |
| 27 | +# Time axis (seconds ago, with most recent on right) |
| 28 | +time_seconds = np.arange(n_points) * 0.1 |
| 29 | + |
| 30 | +# Visible window (last 60 points) |
| 31 | +visible_time = time_seconds[-visible_points:] |
| 32 | +visible_cpu = cpu_usage[-visible_points:] |
| 33 | + |
| 34 | +# Current value for prominent display |
| 35 | +current_value = visible_cpu[-1] |
| 36 | + |
| 37 | +# Create plot |
| 38 | +fig, ax = plt.subplots(figsize=(16, 9)) |
| 39 | + |
| 40 | +# Create gradient fill effect using multiple fills with decreasing alpha |
| 41 | +n_gradient = 10 |
| 42 | +for i in range(n_gradient): |
| 43 | + alpha_fill = 0.05 + 0.15 * (i / n_gradient) |
| 44 | + y_offset = visible_cpu * (1 - 0.02 * (n_gradient - i)) |
| 45 | + ax.fill_between(visible_time, 0, y_offset, alpha=alpha_fill, color="#306998", linewidth=0) |
| 46 | + |
| 47 | +# Main line with gradient effect (darker at right/newer) |
| 48 | +colors = np.linspace(0.3, 1.0, visible_points) |
| 49 | +for i in range(len(visible_time) - 1): |
| 50 | + ax.plot( |
| 51 | + visible_time[i : i + 2], |
| 52 | + visible_cpu[i : i + 2], |
| 53 | + color="#306998", |
| 54 | + alpha=colors[i], |
| 55 | + linewidth=3, |
| 56 | + solid_capstyle="round", |
| 57 | + ) |
| 58 | + |
| 59 | +# Fade effect on left edge (older data) |
| 60 | +fade_width = 8 |
| 61 | +for i in range(fade_width): |
| 62 | + fade_alpha = 1 - (fade_width - i) / fade_width |
| 63 | + ax.axvspan(visible_time[i], visible_time[i + 1], alpha=0.3 * (1 - fade_alpha), color="white", zorder=2) |
| 64 | + |
| 65 | +# Arrow indicating scroll direction (data flowing left) |
| 66 | +arrow = FancyArrowPatch( |
| 67 | + (visible_time[5], 85), |
| 68 | + (visible_time[0], 85), |
| 69 | + arrowstyle="->", |
| 70 | + mutation_scale=25, |
| 71 | + color="#666666", |
| 72 | + linewidth=2, |
| 73 | + alpha=0.7, |
| 74 | +) |
| 75 | +ax.add_patch(arrow) |
| 76 | +ax.text(visible_time[2], 90, "← older data", fontsize=14, color="#666666", ha="center") |
| 77 | + |
| 78 | +# Current value indicator |
| 79 | +ax.scatter([visible_time[-1]], [current_value], s=300, color="#FFD43B", zorder=5, edgecolor="#306998", linewidth=2) |
| 80 | +ax.annotate( |
| 81 | + f"{current_value:.1f}%", |
| 82 | + (visible_time[-1], current_value), |
| 83 | + xytext=(15, 10), |
| 84 | + textcoords="offset points", |
| 85 | + fontsize=18, |
| 86 | + fontweight="bold", |
| 87 | + color="#306998", |
| 88 | + bbox={"boxstyle": "round,pad=0.3", "facecolor": "#FFD43B", "edgecolor": "#306998", "alpha": 0.9}, |
| 89 | +) |
| 90 | + |
| 91 | +# Current time label |
| 92 | +ax.text(visible_time[-1], -8, "NOW", fontsize=14, fontweight="bold", color="#306998", ha="center") |
| 93 | + |
| 94 | +# Styling |
| 95 | +ax.set_xlabel("Time (seconds)", fontsize=20) |
| 96 | +ax.set_ylabel("CPU Usage (%)", fontsize=20) |
| 97 | +ax.set_title("line-realtime · matplotlib · pyplots.ai", fontsize=24) |
| 98 | +ax.tick_params(axis="both", labelsize=16) |
| 99 | + |
| 100 | +# Y-axis from 0 to 100 for CPU percentage |
| 101 | +ax.set_ylim(-12, 105) |
| 102 | +ax.set_xlim(visible_time[0] - 0.2, visible_time[-1] + 0.8) |
| 103 | + |
| 104 | +# Grid |
| 105 | +ax.grid(True, alpha=0.3, linestyle="--") |
| 106 | + |
| 107 | +# Add horizontal threshold line |
| 108 | +ax.axhline(y=80, color="#CC4444", linestyle="--", linewidth=2, alpha=0.6) |
| 109 | +ax.text(visible_time[-1] + 0.3, 80, "Warning", fontsize=12, color="#CC4444", va="center") |
| 110 | + |
| 111 | +plt.tight_layout() |
| 112 | +plt.savefig("plot.png", dpi=300, bbox_inches="tight") |
0 commit comments