基于Pandas DataFrame的3D成绩相关性可视化需求(标记大小映射人数)
3D可视化学生成绩组合的实现方案
步骤1:预处理数据,统计成绩组合的人数
先统计每个(数学、科学、英语)成绩组合的出现次数,这是后续标记大小的核心依据:
import pandas as pd import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # 初始化数据 data = [[1, 2, 3], [2, 2, 3], [1, 1, 2], [2, 2, 2], [2, 3, 2], [2, 3, 3], [1, 1, 1], [3, 3, 3], [3, 3, 2], [1, 2, 1], [1, 3, 1], [3, 1, 3], [2, 1, 2], [3, 3, 3], [2, 2, 2], [3, 2, 1], [3, 2, 2], [2, 2, 1], [1, 1, 3], [1, 3, 2], [1, 2, 3]] df = pd.DataFrame(data, columns=['Math', 'Science', 'English']) # 统计每个成绩组合的人数N grouped_df = df.groupby(['Math', 'Science', 'English']).size().reset_index(name='N')
方案1:科目作为X/Y/Z轴,成绩等级为坐标值
直接将三个科目对应3D坐标系的X、Y、Z轴,每个点的坐标是该成绩组合的三科等级,标记大小由组合人数N决定,颜色可按单科目成绩或三科综合成绩编码:
# 创建3D绘图对象 fig = plt.figure(figsize=(10,8)) ax = fig.add_subplot(111, projection='3d') # 提取坐标和参数 x = grouped_df['Math'] y = grouped_df['Science'] z = grouped_df['English'] n = grouped_df['N'] # 用数学成绩作为颜色编码依据,也可替换为Science或三科平均分 color = grouped_df['Math'] # 绘制3D散点图:s控制标记大小,c控制颜色,alpha调整透明度 scatter = ax.scatter(x, y, z, s=n*150, c=color, cmap='coolwarm', alpha=0.7, edgecolors='black') # 设置坐标轴标签和标题 ax.set_xlabel('Math Grade') ax.set_ylabel('Science Grade') ax.set_zlabel('English Grade') ax.set_title('3D Distribution of Student Grade Combinations') # 添加颜色条说明颜色对应关系 plt.colorbar(scatter, label='Math Grade (1=Poor, 2=Average, 3=Good)') # 固定坐标轴刻度为成绩等级 ax.set_xticks([1,2,3]) ax.set_yticks([1,2,3]) ax.set_zticks([1,2,3]) plt.show()
效果说明:每个点代表一种成绩组合,点越大说明该组合的学生越多;颜色直观反映数学成绩高低,可灵活替换为其他科目或三科平均分的颜色映射。
方案2:成绩等级作为X/Y/Z轴,科目作为分组维度
将成绩等级(1/2/3)设为坐标轴,每个坐标轴对应一个科目,点的位置表示某科目在该等级的人数,标记大小对应人数,颜色区分科目:
# 统计每个科目各成绩等级的人数 subject_grade_counts = [] for subject in ['Math', 'Science', 'English']: counts = df[subject].value_counts().reset_index() counts.columns = ['Grade', 'N'] counts['Subject'] = subject subject_grade_counts.append(counts) subject_df = pd.concat(subject_grade_counts) # 映射科目到坐标值(用于区分不同科目的点位置) subject_map = {'Math': 1, 'Science': 2, 'English': 3} subject_df['Axis'] = subject_df['Subject'].map(subject_map) # 创建3D绘图对象 fig = plt.figure(figsize=(10,8)) ax = fig.add_subplot(111, projection='3d') # 按科目分组绘图 colors = {'Math': 'red', 'Science': 'green', 'English': 'blue'} for subject in subject_map.keys(): subset = subject_df[subject_df['Subject'] == subject] ax.scatter(subset['Grade'], subset['Axis'], subset['Grade'], s=subset['N']*200, c=colors[subject], label=subject, alpha=0.7, edgecolors='black') # 设置坐标轴标签和标题 ax.set_xlabel('Grade Level (1=Poor, 2=Average, 3=Good)') ax.set_ylabel('Subject') ax.set_zlabel('Grade Level') ax.set_title('3D Distribution of Grade Counts by Subject') # 配置刻度和图例 ax.set_xticks([1,2,3]) ax.set_yticks([1,2,3]) ax.set_zticks([1,2,3]) ax.set_yticklabels(['Math', 'Science', 'English']) ax.legend() plt.show()
效果说明:每个点代表某科目在特定成绩等级的人数,点越大说明该科目该等级的学生越多;颜色直接区分不同科目,可直观对比同一成绩等级下不同科目的人数分布,或同一科目不同成绩等级的人数差异。
关键细节调整
- 标记大小的系数(如
n*150)可根据显示效果灵活调整,避免点过大或过小。 - 颜色编码可扩展:比如用三科成绩的组合作为分类变量,通过
pd.Categorical生成自定义颜色映射;或用成绩等级的综合评分作为连续颜色值。 - 若需要交互功能(如悬停显示详细信息),可改用
plotly库的3D散点图实现。
内容的提问来源于stack exchange,提问作者Serena
相关产品推荐
相关产品推荐

