ggplot2堆叠条形图:基于多维度对条形重新排序
Hey 👋,我来帮你搞定这个堆叠条形图加多维排序的需求!咱们用Python的pandas+matplotlib+seaborn来实现,代码直接就能跑,还能灵活调整排序逻辑~
实现堆叠条形图与多维度排序
1. 先把数据准备好
首先把你给的数据集转换成pandas的DataFrame,方便后续处理:
import pandas as pd import matplotlib.pyplot as plt import seaborn as sns # 构建数据集 data = { 'Word': ['aambeeld', 'aambeeld', 'bezem', 'bezem', 'broodrooster', 'broodrooster', 'buis', 'buis'], 'Cognate': ['Cognate', 'Cognate', 'Cognate', 'Cognate', 'Non-cognate', 'Non-cognate', 'Non-cognate', 'Non-cognate'], 'TestingMoment': ['Main2', 'Main4', 'Main2', 'Main4', 'Main2', 'Main4', 'Main2', 'Main4'], 'Score': [0.35, 0.767, 1.0, 1.0, 0.5428571, 0.5714286, 0.4545455, 0.6363636], 'freq': [10, 10, 5, 5, 14, 14, 11, 11] } data_words = pd.DataFrame(data)
2. 自定义多维度排序逻辑
这里咱们可以根据需求灵活设置排序规则,比如我举个常用的例子:先按Cognate类型分组(让Cognate类的词排在前面),再按每个词的平均Score降序排列(表现好的词靠前),最后按单词字母顺序兜底。
代码实现如下:
# 计算每个单词的平均Score,用来做排序依据 word_avg_score = data_words.groupby('Word')['Score'].mean().reset_index(name='AvgScore') data_words = data_words.merge(word_avg_score, on='Word') # 执行多维度排序:Cognate升序(Cognate在前)→ AvgScore降序 → Word升序 sorted_word_order = data_words.sort_values( by=['Cognate', 'AvgScore', 'Word'], ascending=[True, False, True] )['Word'].unique()
要是你想换其他排序规则,比如按freq降序、或者让Non-cognate类先出现,只需要修改sort_values里的参数就行:
- 比如按
Cognate降序(Non-cognate在前)+freq降序:sorted_word_order = data_words.sort_values(by=['Cognate', 'freq'], ascending=[False, False])['Word'].unique() - 比如只按Main4时刻的Score降序:
main4_data = data_words[data_words['TestingMoment'] == 'Main4'] sorted_word_order = main4_data.sort_values(by='Score', ascending=False)['Word'].unique()
3. 绘制堆叠条形图
接下来咱们把排序好的单词作为X轴,把TestingMoment作为堆叠的类别,绘制堆叠条形图:
# 设置绘图风格,让图表更好看 sns.set_style("whitegrid") plt.figure(figsize=(12, 6)) # 获取要堆叠的测试时刻类别 test_moments = data_words['TestingMoment'].unique() # 初始化堆叠的底部位置 bottom = pd.Series([0]*len(sorted_word_order), index=sorted_word_order) # 循环绘制每个测试时刻的条形 for moment in test_moments: # 筛选对应时刻的数据,并按排序后的单词顺序排列 moment_data = data_words[data_words['TestingMoment'] == moment].set_index('Word').loc[sorted_word_order] # 绘制堆叠条形 plt.bar(sorted_word_order, moment_data['Score'], bottom=bottom, label=moment) # 更新下一个条形的底部位置 bottom += moment_data['Score'] # 添加图表标签和标题 plt.xlabel('单词', fontsize=12) plt.ylabel('得分', fontsize=12) plt.title('单词得分堆叠条形图(按同源词类型+平均得分排序)', fontsize=14) plt.legend(title='测试时刻') # 旋转X轴标签避免重叠 plt.xticks(rotation=45, ha='right') # 自动调整布局,防止标签被截断 plt.tight_layout() plt.show()
运行这段代码后,你就能得到一个按自定义规则排序的堆叠条形图啦,每个单词的两个测试时刻得分会堆叠在一起,一目了然~
内容的提问来源于stack exchange,提问作者Johanna
相关产品推荐
相关产品推荐

