在Python中可视化三类分类变量(城市/职业/血型)的技术方案问询
解决方案1:用原始数据直接绘制Swarmplot
其实Seaborn的swarmplot并不要求某一轴必须是定量变量——它完全支持两个分类轴,只要你有每个样本的原始记录(正好你手里有500行的原始df)。你之前可能误用了聚合后的数据来调用swarmplot,才导致报错。直接用原始数据就能实现你想要的效果:
import seaborn as sns import matplotlib.pyplot as plt # 设置绘图风格 sns.set_style("whitegrid") # 绘制swarmplot plt.figure(figsize=(12, 8)) sns.swarmplot( data=df, x="City", y="Occupation", hue="Blood Type", size=5, # 调整点的大小避免过度拥挤 dodge=True # 按血型分组抖动,减少点的重叠 ) # 添加标题和标签 plt.title("Distribution of Blood Types by City and Occupation", fontsize=14) plt.xlabel("City", fontsize=12) plt.ylabel("Occupation", fontsize=12) # 将图例放在图外避免遮挡 plt.legend(title="Blood Type", bbox_to_anchor=(1.05, 1), loc="upper left") plt.tight_layout() plt.show()
这个图会在每个City-Occupation交叉位置,用不同颜色展示每个样本的血型,抖动效果会避免点完全重叠,直观呈现各分组的分布情况。
解决方案2:4×5子图网格的分类柱状图
如果你想展示聚合后的计数(而不是单个样本),可以创建4行(对应4种Occupation)×5列(对应5种City)的子图网格,每个子图展示该组合下各血型的计数:
首先,先把聚合后的数据整理成更易处理的格式:
# 获取分组后的计数数据,并重置索引简化结构 grouped_df = df.groupby(by=['City','Occupation','Blood Type']).count().unstack(level=1) # 移除冗余的顶层列名 grouped_df.columns = grouped_df.columns.droplevel(0) grouped_df = grouped_df.reset_index()
然后绘制子图网格:
import matplotlib.pyplot as plt # 定义子图布局:4行(职业)×5列(城市) fig, axes = plt.subplots(nrows=4, ncols=5, figsize=(18, 12)) # 调整子图间的间距 fig.subplots_adjust(hspace=0.4, wspace=0.3) # 获取所有唯一的职业和城市值 unique_occupations = df['Occupation'].unique() unique_cities = df['City'].unique() # 循环绘制每个子图 for i, occupation in enumerate(unique_occupations): for j, city in enumerate(unique_cities): # 筛选当前城市+职业组合的数据 subset = grouped_df[(grouped_df['City'] == city) & (grouped_df.index.get_level_values(1) == occupation)] ax = axes[i, j] # 绘制柱状图 subset.plot(kind='bar', x='Blood Type', y=occupation, ax=ax, legend=False) # 设置子图标题和标签 ax.set_title(f"{city}\n{occupation}", fontsize=10) ax.set_xlabel("Blood Type", fontsize=8) ax.set_ylabel("Count", fontsize=8) ax.tick_params(axis='both', labelsize=7) # 添加整体标题 fig.suptitle("Blood Type Counts by City and Occupation", fontsize=16, y=1.02) plt.tight_layout() plt.show()
这里的关键点:
- 先把分组后的多层索引数据扁平化,方便后续筛选
- 循环遍历每个职业和城市的组合,在对应的子图中绘制柱状图
- 调整子图间距、标题和标签大小,保证整体布局美观且信息清晰
这样你就能得到一个整齐的网格,每个子图清晰展示特定城市和职业下各血型的数量分布。
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

