Python非数值(分类)数据可视化:基于给定DataFrame绘制指定要求柱状图
实现方案
思路说明
- 先将分类等级
Low/Medium/High映射为数值,用于确定柱子高度和标记位置 - 对同一日期下同一item的多个取值,取最高等级作为柱状图高度,其余取值对应位置添加标记点
- 调整X轴刻度为日期,Y轴刻度替换回分类文本
完整代码
import pandas as pd import matplotlib.pyplot as plt # 构造示例DataFrame data = { "date": ["01-01-2021", "02-01-2021", "02-01-2021", "03-01-2021"], "item_1": ["Low", "High", "Low", "Medium"], "item_2": ["High", "Low", "Low", "High"] } df = pd.DataFrame(data) # 等级数值映射 level_map = {"Low": 1, "Medium": 2, "High": 3} # 宽表转长表便于批量处理 df_long = df.melt(id_vars="date", value_vars=["item_1", "item_2"], var_name="item", value_name="level") df_long["level_val"] = df_long["level"].map(level_map) # 配置绘图基础参数 bar_width = 0.35 dates = df["date"].unique() x = range(len(dates)) colors = ["#1f77b4", "#ff7f0e"] items = ["item_1", "item_2"] plt.figure(figsize=(10,6)) # 遍历每个item绘制柱子和标记 for idx, item in enumerate(items): # 计算当前item的柱子X轴偏移,避免同一日期下两个柱子重叠 bar_x = [i + bar_width*idx - bar_width/2 for i in x] # 取每个日期下当前item的最高等级作为柱子高度 group_max = df_long[df_long["item"] == item].groupby("date")["level_val"].max().reindex(dates) plt.bar(bar_x, group_max, width=bar_width, label=item, color=colors[idx], alpha=0.7) # 给所有等级的位置添加标记 group_all = df_long[df_long["item"] == item].groupby("date")["level_val"].apply(list).reindex(dates) for date_idx, vals in enumerate(group_all): for v in vals: # 用红色星号作为标记,层级调高避免被柱子遮挡 plt.scatter(bar_x[date_idx], v, marker="*", s=200, c="red", zorder=10) # 调整轴显示样式 plt.xticks(x, dates) plt.yticks([1,2,3], ["Low", "Medium", "High"]) plt.xlabel("日期") plt.ylabel("等级") plt.legend() plt.tight_layout() plt.show()
参数调整说明
- 可修改
colors参数自定义柱子颜色 - 可修改
marker、s参数调整标记的样式和大小 - 可修改
figsize参数调整画布尺寸
内容的提问来源于stack exchange,提问作者TK7372
相关产品推荐
相关产品推荐

