如何对子图 x 轴上的值进行排序 导入和测试数据帧将字母等级映射到数字将字母等级设置为分类和有序

问题描述

我使用了另一个示例中的代码,所以我不确定在哪里进行更改。我所有的条形都按频率组织的 x 值按降序排列,但我想按 x 轴组织条形,x 轴值按升序排列。所以从 0.7 到 4.3。如何更新我的代码,以便它们按 x 轴值按升序排列?

image of graphs

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

def grade_distribution():
    
    # importing datasets
    df=pd.read_csv('assets/class_grades.csv')
    
    # dropping first column
    df.drop(df.columns[[0]],axis=1,inplace=True)

    # updating grade values
    df['EECS545_grade'] = df['EECS545_grade'].replace({'A+': '4.3','A': '4.0','A-': '3.7','B+': '3.3','B': '3.0','B-': '2.7','C+': '2.3','C': '2.0','C-': '1.7','D+': '1.3','D': '1.0','D-': '0.7','E': '0'}) 
    df['ECON101_grade'] = df['ECON101_grade'].replace({'A+': '4.3','E': '0'}) 
    df['ENGLISH125_grade'] = df['ENGLISH125_grade'].replace({'A+': '4.3','E': '0'}) 
    df['MATH217_grade'] = df['MATH217_grade'].replace({'A+': '4.3','E': '0'}) 
    df['DATASCI306_grade'] = df['DATASCI306_grade'].replace({'A+': '4.3','E': '0'}) 
    df['STATS250_grade'] = df['STATS250_grade'].replace({'A+': '4.3','E': '0'}) 
    
    # dropping NaN values
    df.dropna(inplace=True)
    
    cols_to_plot = ['EECS545_grade','ECON101_grade','ENGLISH125_grade','MATH217_grade','DATASCI306_grade','STATS250_grade']
    fig,axs = plt.subplots(nrows=2,ncols=3)
    fig.set_size_inches(20,10)
    fig.subplots_adjust(wspace=0.2)
    fig.subplots_adjust(hspace=0.5)
    
    for col,ax in zip(cols_to_plot,axs.flatten()):
        dftemp = df[col].value_counts()
        ax.bar(dftemp.index,list(dftemp))
        ax.set_title(col)
        ax.tick_params(axis='x',labelrotation=30)

    plt.show()
    
grade_distribution()

解决方法

  • 该顺序的问题是使用无序字符串作为数字等级。
    1. 可以通过将字母等级映射到数字而不是字符串来解决排序问题。
    2. 可以通过将字母设置为有序分类类型来解决排序问题。
  • 这应该是一个 countplot,而不是一个 histogram,因为数据不是 binned 来传达分布,数据只是针对每个类别进行计数。
    • 代码显示 ax.bar(dftemp.index,list(dftemp)) 正在绘制
  • 通过使用 .stack() 将数据帧转换为长格式,然后使用 seaborn.catplot,只需四行代码即可绘制整个图。
    • seabornmatplotlib
    • 的高级 API
  • 版本:
    • pandas v1.2.3
    • seaborn v0.11.1
    • matplotlib v3.3.4 - seabornpandas 依赖项。

导入和测试数据帧

import pandas as pd
import numpy as np  # for test data
import seaborn as sns

# test data
np.random.seed(365)

classes = ['EECS545_grade','ECON101_grade','ENGLISH125_grade','MATH217_grade','DATASCI306_grade','STATS250_grade']
grades = ['A+','A','A-','B+','B','B-','C+','C','C-','D+','D','D-','E']
grades_array = np.random.choice(grades,(1000,6))

# given a wide dataframe 
df = pd.DataFrame(grades_array,columns=classes)

# display(df.head(3))
  EECS545_grade ECON101_grade ENGLISH125_grade MATH217_grade DATASCI306_grade STATS250_grade
0            A-             B                A            D-                E             B-
1            A-            A-               D+             D               C-              B
2            A+             E               B+            B+                C              C

将字母等级映射到数字

# numeric grade
nums = [4.3,4.0,3.7,3.3,3.0,2.7,2.3,2.0,1.7,1.3,1.0,0.7,0.0]

# dict of letter grades with numeric values (not string values)
grade_map = dict(zip(grades,nums))

# print(grade_map) and see that letter grades are now mapped to numbers,not strings
{'A+': 4.3,'A': 4.0,'A-': 3.7,'B+': 3.3,'B': 3.0,'B-': 2.7,'C+': 2.3,'C': 2.0,'C-': 1.7,'D+': 1.3,'D': 1.0,'D-': 0.7,'E': 0.0}

# stack the dataframe
dfl = df.stack().reset_index(name='grades').drop(['level_0'],axis=1).rename({'level_1': 'classes'},axis=1)

# map grades to numbers
dfl['grades_num'] = dfl.grades.map(grade_map)

# display(dfl.head(3))
            classes grades  grades_num
0     EECS545_grade     A-         3.7
1     ECON101_grade      B         3.0
2  ENGLISH125_grade      A         4.0

# plot dfl
sns.catplot(data=dfl,col='classes',col_wrap=3,x='grades_num',kind='count',color='lightgreen')

enter image description here

将字母等级设置为分类和有序

  • 实际上没有必要将字母成绩转换为数字成绩
  • 使用 'grades'Categorypd.Categorical 列设置为 ordered=True 类型。
# stack the dataframe
dfl = df.stack().reset_index(name='grades').drop(['level_0'],axis=1)

# convert grades letters to categorical and ordered
dfl.grades = pd.Categorical(dfl.grades,categories=grades,ordered=True)

# plot grades
sns.catplot(data=dfl,x='grades',color='orchid')

enter image description here

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...