如何用Pandas多列分组并绘制符合需求的Feature路线图柱状图?
解决方案:基于Rally数据集生成Feature路线图
一、数据聚合:计算Feature核心指标
首先用Pandas对原始数据按Feature ID分组,提取每个Feature的关键信息:用户故事数量、起止Sprint、总点数,以及Sprint跨度。
import pandas as pd # 导入数据集(示例数据,实际可替换为pd.read_csv读取文件) data = { "Feature ID": ["01", "01", "02", "03", "01", "01", "04"], "User Story ID": [101, 102, 103, 104, 105, 106, 107], "Sprint": [1, 1, 1, 1, 2, 2, 2], "Points": [3, 5, 2, 5, 5, 2, 2] } df = pd.DataFrame(data) # 分组计算统计量 feature_summary = df.groupby("Feature ID").agg( Story_Count=("User Story ID", "count"), Start_Sprint=("Sprint", "min"), End_Sprint=("Sprint", "max"), Total_Points=("Points", "sum") ).reset_index() # 计算Sprint覆盖的跨度 feature_summary["Sprint_Span"] = feature_summary["End_Sprint"] - feature_summary["Start_Sprint"] + 1
执行后得到的feature_summary包含所有核心指标:
| Feature ID | Story_Count | Start_Sprint | End_Sprint | Total_Points | Sprint_Span |
|---|---|---|---|---|---|
| 01 | 4 | 1 | 2 | 15 | 2 |
| 02 | 1 | 1 | 1 | 2 | 1 |
| 03 | 1 | 1 | 1 | 5 | 1 |
| 04 | 1 | 2 | 2 | 2 | 1 |
二、可视化:生成Feature路线图
1. 简洁版:展示Feature的Sprint跨度与核心指标
用横向条形图直观展示每个Feature的Sprint覆盖范围,同时标注故事数和总点数:
import matplotlib.pyplot as plt plt.figure(figsize=(10, 6)) y_pos = range(len(feature_summary)) # 绘制覆盖Sprint的条形 plt.barh(y_pos, feature_summary["Sprint_Span"], left=feature_summary["Start_Sprint"], height=0.6, color="#4CAF50") # 为每个条形添加标注 for i, row in feature_summary.iterrows(): x_center = row["Start_Sprint"] + row["Sprint_Span"] / 2 plt.text(x_center, y_pos[i], f"Stories: {row['Story_Count']}\nPoints: {row['Total_Points']}", ha="center", va="center", color="white", fontweight="bold") # 设置坐标轴与样式 plt.yticks(y_pos, feature_summary["Feature ID"]) plt.xlabel("Sprint Number") plt.ylabel("Feature ID") plt.title("Feature Roadmap: Sprint Coverage & Metrics") plt.xticks(range(feature_summary["Start_Sprint"].min(), feature_summary["End_Sprint"].max() + 1)) plt.grid(axis="x", linestyle="--", alpha=0.7) plt.tight_layout() plt.show()
2. 细致版:展示每个User Story的分布
如果需要看每个Feature下具体用户故事的Sprint分布和点数,可以用如下代码:
df_sorted = df.sort_values("Feature ID") plt.figure(figsize=(10, 8)) y_offset = 0 feature_y_map = {} for feature_id, group in df_sorted.groupby("Feature ID"): feature_y_map[feature_id] = y_offset # 为每个User Story绘制单独的条形 for _, story in group.iterrows(): plt.barh(y_offset, 1, left=story["Sprint"] - 0.5, height=0.4, color=f"C{int(feature_id)}") plt.text(story["Sprint"], y_offset, f"#{story['User Story ID']} ({story['Points']})", ha="center", va="center", fontsize=9) y_offset += 1 # 设置坐标轴与样式 plt.yticks(range(len(feature_y_map)), feature_y_map.keys()) plt.xlabel("Sprint Number") plt.ylabel("Feature ID") plt.title("Feature Roadmap with Individual User Stories") plt.xticks(range(df["Sprint"].min(), df["Sprint"].max() + 1)) plt.grid(axis="x", linestyle="--", alpha=0.7) plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者Ammy
相关产品推荐
相关产品推荐

