|
| 1 | +""" pyplots.ai |
| 2 | +bar-feature-importance: Feature Importance Bar Chart |
| 3 | +Library: pygal 3.1.0 | Python 3.13.11 |
| 4 | +Quality: 92/100 | Created: 2025-12-26 |
| 5 | +""" |
| 6 | + |
| 7 | +import pygal |
| 8 | +from pygal.style import Style |
| 9 | + |
| 10 | + |
| 11 | +# Data - Feature importances from a RandomForest classifier (house price prediction) |
| 12 | +features = [ |
| 13 | + "OverallQual", |
| 14 | + "GrLivArea", |
| 15 | + "TotalBsmtSF", |
| 16 | + "GarageCars", |
| 17 | + "YearBuilt", |
| 18 | + "FullBath", |
| 19 | + "TotRmsAbvGrd", |
| 20 | + "Fireplaces", |
| 21 | + "BsmtQual", |
| 22 | + "LotArea", |
| 23 | + "GarageArea", |
| 24 | + "YearRemodAdd", |
| 25 | + "KitchenQual", |
| 26 | + "Neighborhood", |
| 27 | + "ExterQual", |
| 28 | +] |
| 29 | +importances = [0.245, 0.182, 0.098, 0.087, 0.076, 0.054, 0.048, 0.042, 0.038, 0.035, 0.031, 0.024, 0.019, 0.012, 0.009] |
| 30 | + |
| 31 | +# Sort by importance (descending) - pygal renders bottom to top, so reverse for highest at top |
| 32 | +sorted_pairs = sorted(zip(features, importances, strict=True), key=lambda x: x[1], reverse=False) |
| 33 | +sorted_features = [p[0] for p in sorted_pairs] |
| 34 | +sorted_importances = [p[1] for p in sorted_pairs] |
| 35 | + |
| 36 | +# Generate colors from light blue to Python Blue based on importance |
| 37 | +min_imp = min(sorted_importances) |
| 38 | +max_imp = max(sorted_importances) |
| 39 | + |
| 40 | + |
| 41 | +def importance_to_color(value): |
| 42 | + """Map importance to color gradient: light blue -> Python Blue (#306998)""" |
| 43 | + if max_imp == min_imp: |
| 44 | + ratio = 1 |
| 45 | + else: |
| 46 | + ratio = (value - min_imp) / (max_imp - min_imp) |
| 47 | + # Interpolate from light blue (180, 210, 240) to Python Blue (48, 105, 152) |
| 48 | + r = int(180 - ratio * (180 - 48)) |
| 49 | + g = int(210 - ratio * (210 - 105)) |
| 50 | + b = int(240 - ratio * (240 - 152)) |
| 51 | + return f"#{r:02x}{g:02x}{b:02x}" |
| 52 | + |
| 53 | + |
| 54 | +# Custom style for large canvas (4800 x 2700 px) |
| 55 | +custom_style = Style( |
| 56 | + background="white", |
| 57 | + plot_background="white", |
| 58 | + foreground="#333333", |
| 59 | + foreground_strong="#333333", |
| 60 | + foreground_subtle="#666666", |
| 61 | + colors=("#306998",), |
| 62 | + font_family="sans-serif", |
| 63 | + title_font_size=72, |
| 64 | + label_font_size=42, |
| 65 | + major_label_font_size=38, |
| 66 | + legend_font_size=40, |
| 67 | + value_font_size=36, |
| 68 | + value_colors=("#333333",), |
| 69 | + stroke_width=0, |
| 70 | +) |
| 71 | + |
| 72 | +# Create horizontal bar chart |
| 73 | +chart = pygal.HorizontalBar( |
| 74 | + width=4800, |
| 75 | + height=2700, |
| 76 | + style=custom_style, |
| 77 | + title="bar-feature-importance · pygal · pyplots.ai", |
| 78 | + x_title="Importance Score", |
| 79 | + show_legend=False, |
| 80 | + show_y_guides=False, |
| 81 | + show_x_guides=True, |
| 82 | + print_values=True, |
| 83 | + print_values_position="top", |
| 84 | + value_formatter=lambda x: f"{x:.3f}", |
| 85 | + margin=60, |
| 86 | + spacing=15, |
| 87 | + truncate_label=-1, |
| 88 | + x_label_rotation=0, |
| 89 | +) |
| 90 | + |
| 91 | +# Set feature names as y-axis labels (x_labels become y-axis in horizontal chart) |
| 92 | +chart.x_labels = sorted_features |
| 93 | + |
| 94 | +# Add data with individual colors per bar |
| 95 | +bar_data = [{"value": imp, "color": importance_to_color(imp)} for imp in sorted_importances] |
| 96 | +chart.add("Importance", bar_data) |
| 97 | + |
| 98 | +# Save outputs |
| 99 | +chart.render_to_file("plot.html") |
| 100 | +chart.render_to_png("plot.png") |
0 commit comments