|
| 1 | +""" pyplots.ai |
| 2 | +box-horizontal: Horizontal Box Plot |
| 3 | +Library: pygal 3.1.0 | Python 3.13.11 |
| 4 | +Quality: 68/100 | Created: 2025-12-30 |
| 5 | +""" |
| 6 | + |
| 7 | +import numpy as np |
| 8 | +import pygal |
| 9 | +from pygal.style import Style |
| 10 | + |
| 11 | + |
| 12 | +# Create HorizontalBox dynamically (pygal doesn't include it natively) |
| 13 | +# This uses pygal's standard mixin pattern for horizontal chart variants |
| 14 | +HorizontalBox = type("HorizontalBox", (pygal.graph.horizontal.HorizontalGraph, pygal.graph.box.Box), {}) |
| 15 | + |
| 16 | +# Data - Response times for different service types (in milliseconds) |
| 17 | +np.random.seed(42) |
| 18 | +categories = ["Database Query", "API Gateway", "Authentication", "File Upload", "Image Processing"] |
| 19 | +data = { |
| 20 | + "Database Query": np.random.lognormal(3.5, 0.6, 80), |
| 21 | + "API Gateway": np.random.lognormal(3.2, 0.4, 80), |
| 22 | + "Authentication": np.random.lognormal(3.8, 0.5, 80), |
| 23 | + "File Upload": np.random.lognormal(4.2, 0.7, 80), |
| 24 | + "Image Processing": np.random.lognormal(4.5, 0.6, 80), |
| 25 | +} |
| 26 | + |
| 27 | +# Add outliers with more moderate values to avoid excessive whitespace |
| 28 | +data["Database Query"] = np.append(data["Database Query"], [180, 220, 280]) |
| 29 | +data["File Upload"] = np.append(data["File Upload"], [350, 420]) |
| 30 | +data["Image Processing"] = np.append(data["Image Processing"], [450, 520, 580]) |
| 31 | + |
| 32 | +# Custom style using PyPlots colors - scaled for 4800x2700 canvas |
| 33 | +custom_style = Style( |
| 34 | + background="white", |
| 35 | + plot_background="white", |
| 36 | + foreground="#333333", |
| 37 | + foreground_strong="#333333", |
| 38 | + foreground_subtle="#666666", |
| 39 | + colors=("#306998", "#FFD43B", "#4CAF50", "#FF5722", "#9C27B0"), |
| 40 | + title_font_size=60, |
| 41 | + label_font_size=40, |
| 42 | + major_label_font_size=36, |
| 43 | + legend_font_size=36, |
| 44 | + value_font_size=32, |
| 45 | +) |
| 46 | + |
| 47 | +# Create horizontal box chart with category labels displayed on y-axis |
| 48 | +chart = HorizontalBox( |
| 49 | + width=4800, |
| 50 | + height=2700, |
| 51 | + style=custom_style, |
| 52 | + title="box-horizontal · pygal · pyplots.ai", |
| 53 | + x_title="Response Time (ms)", |
| 54 | + show_legend=True, |
| 55 | + legend_at_bottom=True, |
| 56 | + legend_at_bottom_columns=5, |
| 57 | + legend_box_size=30, |
| 58 | + show_y_guides=True, |
| 59 | + show_x_guides=False, |
| 60 | + margin=50, |
| 61 | + margin_left=400, |
| 62 | + margin_bottom=200, |
| 63 | + spacing=60, |
| 64 | + box_mode="tukey", |
| 65 | + truncate_label=-1, |
| 66 | + truncate_legend=-1, |
| 67 | + dots_size=8, |
| 68 | +) |
| 69 | + |
| 70 | +# Set category labels on y-axis (in horizontal mode, x_labels display on the y-axis) |
| 71 | +chart.x_labels = categories |
| 72 | + |
| 73 | +# Add data for each category (legend entries match the x_labels for cross-referencing) |
| 74 | +for category in categories: |
| 75 | + chart.add(category, data[category].tolist()) |
| 76 | + |
| 77 | +# Save outputs |
| 78 | +chart.render_to_file("plot.html") |
| 79 | +chart.render_to_png("plot.png") |
0 commit comments