Matplotlib多图绘制(嵌套循环):独立生成关联直方图求助
Got it, let's break this down step by step. You want two core components: a colored chart (tailored to your ML weight scenario) where color represents how close each weight vector is to your target, plus independent histograms for every data point. Let's tackle both parts with practical, code-driven solutions using Python (the go-to for ML workflows).
First, we'll build a scatter plot (ideal for 2D weight vectors; adjust for higher dimensions if needed) where each point's color maps to its distance from the target weight. We'll use L2 distance here, but you can swap in MAE or any other proximity metric that fits your use case.
import matplotlib.pyplot as plt import numpy as np # Simulate sample ML weight data: 50 2D weight vectors num_weights = 50 weight_dim = 2 weights = np.random.normal(loc=0, scale=1, size=(num_weights, weight_dim)) # Define your target weight vector target_weights = np.array([0.5, -0.3]) # Calculate proximity (L2 distance) from each weight to the target distances = np.linalg.norm(weights - target_weights, axis=1) # Create the colored scatter plot fig, ax = plt.subplots(figsize=(8, 6)) scatter = ax.scatter( weights[:, 0], weights[:, 1], c=distances, cmap='viridis_r', # Reverse colormap so closer points are brighter s=120, edgecolor='white' ) # Add colorbar to explain proximity scale cbar = plt.colorbar(scatter) cbar.set_label('Distance to Target Weight', fontsize=12) # Label and title the chart ax.set_xlabel('Weight Dimension 1', fontsize=12) ax.set_ylabel('Weight Dimension 2', fontsize=12) ax.set_title('Weight Vectors Colored by Proximity to Target', fontsize=14) plt.tight_layout()
The tricky part is generating separate histograms without overlap. Below are three practical approaches, depending on whether you want static or interactive visuals:
Option 1: Static Inset Histograms (Per-Point in Main Chart)
If you have a small number of weights, add tiny inset histograms directly next to each data point in the main chart. This keeps everything in one view.
# Continuing from the code above for i in range(num_weights): # Create a small inset axis next to the weight point inset_ax = ax.inset_axes([weights[i,0]+0.1, weights[i,1]+0.1, 0.3, 0.3]) # Plot histogram of the current weight vector's dimension values inset_ax.hist(weights[i], bins=5, edgecolor='black', color='#2ecc71') # Clean up the inset to avoid clutter inset_ax.set_xticks([]) inset_ax.set_yticks([]) inset_ax.set_title(f'Weight {i+1}', fontsize=8) plt.show()
Option 2: Interactive Hover Histograms (Plotly)
For larger datasets, static insets get messy. Use Plotly to create an interactive chart where hovering over a weight point displays its corresponding histogram. This is far cleaner for scaling.
import plotly.graph_objects as go import plotly.express as px # Build the main interactive scatter plot fig = px.scatter( x=weights[:,0], y=weights[:,1], color=distances, color_continuous_scale='viridis_r', labels={'x':'Weight Dimension 1', 'y':'Weight Dimension 2', 'color':'Distance to Target'}, title='Weight Vectors with Hover Histograms' ) # Generate custom hover templates with embedded histograms hover_templates = [] for i in range(num_weights): # Create a histogram for the current weight vector hist_fig = px.histogram(weights[i], nbins=5, color_discrete_sequence=['#3498db']) # Convert the histogram to a base64 image for hover embedding hist_img = hist_fig.to_image(format='png', width=200, height=150) # Build the hover template hover_template = f""" <b>Weight {i+1}</b><br> Distance to Target: {distances[i]:.2f}<br> <img src="data:image/png;base64,{hist_img}" width="200" height="150"> """ hover_templates.append(hover_template) # Assign hover templates to each data point fig.update_traces(hovertemplate=hover_templates) fig.show()
Option 3: Separate Subplot Grid
If you want fully independent, standalone histograms (e.g., for reporting), arrange them in a grid alongside the main colored chart.
# Use a smaller number of weights for readability (e.g., 5) num_weights = 5 weights = np.random.normal(loc=0, scale=1, size=(num_weights, weight_dim)) distances = np.linalg.norm(weights - target_weights, axis=1) # Create a 2-row grid: top row for main chart, bottom row for histograms fig = plt.figure(figsize=(14, 8)) # Main colored chart (spans all columns in the top row) ax_main = fig.add_subplot(2, num_weights, (1, num_weights)) scatter = ax_main.scatter(weights[:,0], weights[:,1], c=distances, cmap='viridis_r', s=200) plt.colorbar(scatter, ax=ax_main) ax_main.set_title('Weight Proximity to Target', fontsize=14) ax_main.set_xlabel('Weight Dim 1') ax_main.set_ylabel('Weight Dim 2') # Add individual histograms to the bottom row for i in range(num_weights): ax_hist = fig.add_subplot(2, num_weights, num_weights + 1 + i) ax_hist.hist(weights[i], bins=5, edgecolor='black', color='#e74c3c') ax_hist.set_title(f'Weight {i+1}', fontsize=10) ax_hist.set_xlabel('Weight Value') ax_hist.set_ylabel('Count') plt.tight_layout() plt.show()
If you're using a different tool (like R's ggplot or another library), just let me know and I can adjust these examples to fit your stack. The core idea is decoupling the proximity-based coloring logic from the per-point histogram generation—these approaches should solve your issue of getting independent histograms for every data point.
内容的提问来源于stack exchange,提问作者user9421252

