如何基于嵌套列表数据绘制堆叠条形图?
Got it, let's build this stacked bar chart that adapts to your dynamic cluster data. We'll use matplotlib since it gives us full control over stacking segments and mapping consistent colors to clusters, even when the number of clusters changes.
Step 1: Prepare the Data & Import Libraries
First, let's start by importing the tools we need and defining your input lists:
import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap import numpy as np # Your input data totalpointperxaxis = [6, 9, 13, 5, 14, 382, 26, 2, 45, 2] clusternamesList = [['Cluster1', 'Cluster2'], ['Cluster1', 'Cluster3'], ['Cluster2', 'Cluster4'], ['Cluster1', 'Cluster3'], ['Cluster2', 'Cluster5'], ['Cluster3', 'Cluster6', 'Cluster7'], ['Cluster2', 'Cluster4', 'Cluster6', 'Cluster7'], ['Cluster1', 'Cluster3'], ['Cluster1', 'Cluster2', 'Cluster4', 'Cluster5', 'Cluster6'], ['Cluster1', 'Cluster3']] ppclusterList = [[1, 5], [4, 5], [12, 1], [1, 4], [13, 1], [6, 173, 203], [21, 2, 1, 2], [1, 1], [2, 34, 2, 6, 1], [1, 1]]
Step 2: Collect Unique Clusters & Assign Colors
We need to gather all unique cluster names first, then map each to a distinct color. We'll use a colormap that has enough colors for potential future clusters (like tab20 which has 20 distinct hues):
# Collect all unique cluster names all_clusters = [] for clusters in clusternamesList: all_clusters.extend(clusters) unique_clusters = list(set(all_clusters)) unique_clusters.sort() # Sort for consistent ordering # Create a color map for clusters num_clusters = len(unique_clusters) cmap = plt.get_cmap('tab20', num_clusters) cluster_color_map = {cluster: cmap(i) for i, cluster in enumerate(unique_clusters)}
Step 3: Plot the Stacked Bars
We'll iterate over each bar (x-axis position), stack each cluster's segment on top of the previous one. We'll track the bottom position for each bar to build the stack:
# Set up the plot fig, ax = plt.subplots(figsize=(12, 6)) # X-axis positions (one per bar) x_positions = np.arange(len(totalpointperxaxis)) # Initialize bottom for stacking bottom = np.zeros(len(totalpointperxaxis)) # Iterate through each cluster to plot its segments across all bars for cluster in unique_clusters: # Create an array of values for this cluster (0 if the cluster isn't present in a bar) cluster_values = [] for names, points in zip(clusternamesList, ppclusterList): if cluster in names: idx = names.index(cluster) cluster_values.append(points[idx]) else: cluster_values.append(0) # Plot the segment for this cluster ax.bar(x_positions, cluster_values, bottom=bottom, label=cluster, color=cluster_color_map[cluster]) # Update bottom for the next layer bottom += np.array(cluster_values)
Step 4: Customize the Plot
Add labels, titles, adjust ticks, and handle the legend (since clusters might be many, we'll place it outside the plot):
# Customize axes and labels ax.set_xlabel('Bar Index') ax.set_ylabel('Total Points') ax.set_title('Stacked Bar Chart: Points per Cluster') ax.set_xticks(x_positions) ax.set_xticklabels([f'Bar {i+1}' for i in x_positions]) # Add legend outside the plot to avoid overlapping ax.legend(title='Clusters', bbox_to_anchor=(1.05, 1), loc='upper left') # Adjust layout to fit the legend plt.tight_layout() # Show the plot plt.show()
Key Notes for Dynamic Data
- Automatic Adaptation: If you add more bars to your lists, the code will automatically create new x positions—no hardcoding needed.
- New Clusters: Any new clusters added to
clusternamesListwill be automatically picked up by theall_clusterscollection, assigned a new color, and included in the plot/legend. - Data Consistency Check: For peace of mind, you can add a quick check to ensure each bar's total points match
totalpointperxaxis:# Verify data consistency (optional) for i, (total, points) in enumerate(zip(totalpointperxaxis, ppclusterList)): if sum(points) != total: print(f"Warning: Bar {i+1} total points ({total}) doesn't match sum of cluster points ({sum(points)})")
This code will generate a stacked bar chart exactly like you described, with each cluster's segment colored consistently across all bars, and it will adapt seamlessly as your data grows or changes.
内容的提问来源于stack exchange,提问作者Nishanth Delavictoire

