Guided Project: Visualizing Earnings Based On College Majors

About Dataset : Based on the job outcomes of students who graduated from college between 2010 and 2012. The original data on job outcomes was released by American Community Survey, which conducts surveys and aggregates the data. FiveThirtyEight cleaned the dataset and released it on their Github repo.

Data Dictionary : Each row in the dataset represents a different major in college and contains information on gender diversity, employment rates, median salaries, and more. Here are some of the columns in the dataset:

  • Rank - Rank by median earnings (the dataset is ordered by this column).
  • Major_code - Major code.
  • Major - Major description.
  • Major_category - Category of major.
  • Total - Total number of people with major.
  • Sample_size - Sample size (unweighted) of full-time.
  • Men - Male graduates.
  • Women - Female graduates.
  • ShareWomen - Women as share of total.
  • Employed - Number employed.
  • Median - Median salary of full-time, year-round workers.
  • Low_wage_jobs - Number in low-wage service jobs.
  • Full_time - Number employed 35 hours or more.
  • Part_time - Number employed less than 35 hours.

Aim : Using different plots for visualizations, we will explore questions from the dataset like:

  • Do students in more popular majors make more money? -Using scatter plots
  • How many majors are predominantly male? Predominantly female? -Using histograms
  • Which category of majors have the most students? -Using bar plots
  • Other interesting Questions

Library used : Matplotlib

Types of Plot used -

Scatterplots, Histograms, Multipleplots, Scatter Matrix Plots, Bar Plots, Box Plots,Hexagonal bin plots

Step 1 - Import Libraries

Let's import the libraries we need and remove rows containing null values.

In [1]:
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
In [2]:
# Path of file
grads_file_path = (r'C:\Users\anuja\Downloads\recent-grads_csv.csv')
recent_grads = pd.read_csv(grads_file_path, encoding='Latin-1')

Step 2 - Read Dataset

In [3]:
#  to return the first row formatted as a table.
recent_grads.iloc[0]
Out[3]:
Rank                                        1
Major_code                               2419
Major                   PETROLEUM ENGINEERING
Total                                    2339
Men                                      2057
Women                                     282
Major_category                    Engineering
ShareWomen                           0.120564
Sample_size                                36
Employed                                 1976
Full_time                                1849
Part_time                                 270
Full_time_year_round                     1207
Unemployed                                 37
Unemployment_rate                   0.0183805
Median                                 110000
P25th                                   95000
P75th                                  125000
College_jobs                             1534
Non_college_jobs                          364
Low_wage_jobs                             193
Name: 0, dtype: object
In [4]:
recent_grads.head(2)
Out[4]:
Rank Major_code Major Total Men Women Major_category ShareWomen Sample_size Employed ... Part_time Full_time_year_round Unemployed Unemployment_rate Median P25th P75th College_jobs Non_college_jobs Low_wage_jobs
0 1 2419 PETROLEUM ENGINEERING 2339.0 2057.0 282.0 Engineering 0.120564 36 1976 ... 270 1207 37 0.018381 110000 95000 125000 1534 364 193
1 2 2416 MINING AND MINERAL ENGINEERING 756.0 679.0 77.0 Engineering 0.101852 7 640 ... 170 388 85 0.117241 75000 55000 90000 350 257 50

2 rows × 21 columns

In [5]:
recent_grads.tail(2)
Out[5]:
Rank Major_code Major Total Men Women Major_category ShareWomen Sample_size Employed ... Part_time Full_time_year_round Unemployed Unemployment_rate Median P25th P75th College_jobs Non_college_jobs Low_wage_jobs
171 172 5203 COUNSELING PSYCHOLOGY 4626.0 931.0 3695.0 Psychology & Social Work 0.798746 21 3777 ... 965 2738 214 0.053621 23400 19200 26000 2403 1245 308
172 173 3501 LIBRARY SCIENCE 1098.0 134.0 964.0 Education 0.877960 2 742 ... 237 410 87 0.104946 22000 20000 22000 288 338 192

2 rows × 21 columns

In [6]:
recent_grads.describe()
Out[6]:
Rank Major_code Total Men Women ShareWomen Sample_size Employed Full_time Part_time Full_time_year_round Unemployed Unemployment_rate Median P25th P75th College_jobs Non_college_jobs Low_wage_jobs
count 173.000000 173.000000 172.000000 172.000000 172.000000 172.000000 173.000000 173.000000 173.000000 173.000000 173.000000 173.000000 173.000000 173.000000 173.000000 173.000000 173.000000 173.000000 173.000000
mean 87.000000 3879.815029 39370.081395 16723.406977 22646.674419 0.522223 356.080925 31192.763006 26029.306358 8832.398844 19694.427746 2416.329480 0.068191 40151.445087 29501.445087 51494.219653 12322.635838 13284.497110 3859.017341
std 50.084928 1687.753140 63483.491009 28122.433474 41057.330740 0.231205 618.361022 50675.002241 42869.655092 14648.179473 33160.941514 4112.803148 0.030331 11470.181802 9166.005235 14906.279740 21299.868863 23789.655363 6944.998579
min 1.000000 1100.000000 124.000000 119.000000 0.000000 0.000000 2.000000 0.000000 111.000000 0.000000 111.000000 0.000000 0.000000 22000.000000 18500.000000 22000.000000 0.000000 0.000000 0.000000
25% 44.000000 2403.000000 4549.750000 2177.500000 1778.250000 0.336026 39.000000 3608.000000 3154.000000 1030.000000 2453.000000 304.000000 0.050306 33000.000000 24000.000000 42000.000000 1675.000000 1591.000000 340.000000
50% 87.000000 3608.000000 15104.000000 5434.000000 8386.500000 0.534024 130.000000 11797.000000 10048.000000 3299.000000 7413.000000 893.000000 0.067961 36000.000000 27000.000000 47000.000000 4390.000000 4595.000000 1231.000000
75% 130.000000 5503.000000 38909.750000 14631.000000 22553.750000 0.703299 338.000000 31433.000000 25147.000000 9948.000000 16891.000000 2393.000000 0.087557 45000.000000 33000.000000 60000.000000 14444.000000 11783.000000 3466.000000
max 173.000000 6403.000000 393735.000000 173809.000000 307087.000000 0.968954 4212.000000 307933.000000 251540.000000 115172.000000 199897.000000 28169.000000 0.177226 110000.000000 95000.000000 125000.000000 151643.000000 148395.000000 48207.000000

Step 3- Dropping rows with Missing Values

In [7]:
# number of rows
raw_data_count = len(recent_grads)
print(raw_data_count)
173
In [8]:
# to drop rows containing missing values
recent_grads = recent_grads.dropna()
In [9]:
cleaned_data_count = len(recent_grads)
print(cleaned_data_count)
172

One row contained missing values.

Reading Scatter Plots

image.png

Step 4 -Generating scatter plots in separate jupyter notebook cells to explore the following relations:

  • Sample_size and Median
  • Sample_size and Unemployment_rate
  • Full_time and Median
  • ShareWomen and Unemployment_rate
  • Men and Median
  • Women and Median
In [10]:
recent_grads.plot(x='Sample_size', y='Employed', kind='scatter').set_title('Employed vs. Sample_size')
Out[10]:
Text(0.5, 1.0, 'Employed vs. Sample_size')
  • The scatter plot suggests that there's a strong, positive correlation between the sample size (full time) and the Employed students.
  • The correlation is strong because so many points for both variables are closed to each other.
  • The correlation is positive because, in general, as x increases, y also increases.
In [11]:
recent_grads.plot(x='Sample_size', y='Unemployment_rate', kind='scatter').set_title('Sample_size vs. Unemployment_rate')
Out[11]:
Text(0.5, 1.0, 'Sample_size vs. Unemployment_rate')
  • The scatter plot suggests that there's no correlation between the Sample_size and Unemployment_rate.
  • The vertical line means that the input and output values are irrelevant to each other.
In [12]:
recent_grads.plot(x='Full_time', y='Median', kind='scatter').set_title('Full_time vs. Median')
Out[12]:
Text(0.5, 1.0, 'Full_time vs. Median')
  • The scatter plot suggests that there's no correlation between the Full_time and Median.
  • The vertical line means that the input and output values are irrelevant to each other.
In [13]:
recent_grads.plot(x='ShareWomen', y='Unemployment_rate', kind='scatter').set_title('ShareWomen vs. Unemployment_rate')
Out[13]:
Text(0.5, 1.0, 'ShareWomen vs. Unemployment_rate')
  • The scatter plot suggests that there's no correlation between theShareWomen and Unemployment_rate.
In [14]:
recent_grads.plot(x='Men', y='Median', kind='scatter').set_title('Men vs. Median')
Out[14]:
Text(0.5, 1.0, 'Men vs. Median')
  • The scatter plot suggests that there's no correlation between the Men and Median.
  • The vertical line means that the input and output values are irrelevant to each other.
In [15]:
recent_grads.plot(x='Women', y='Employed', kind='scatter').set_title('Women vs. Median')
Out[15]:
Text(0.5, 1.0, 'Women vs. Median')
  • The scatter plot suggests that there's a positive correlation between the Women and the Median.
  • The correlation is near to strong because so many points for both variables are closed to each other.
  • The correlation is positive because, in general, as x increases, y also increases.

Step 5 -Use the plots to explore the following questions:

  • Do students in more popular majors make more money?
  • Do students that majored in subjects that were majority female make more money?
  • Is there any link between the number of full-time employees and median salary?
In [17]:
recent_grads['Major_category'].unique()
Out[17]:
array(['Engineering', 'Business', 'Physical Sciences',
       'Law & Public Policy', 'Computers & Mathematics',
       'Industrial Arts & Consumer Services', 'Arts', 'Health',
       'Social Science', 'Biology & Life Science', 'Education',
       'Agriculture & Natural Resources', 'Humanities & Liberal Arts',
       'Psychology & Social Work', 'Communications & Journalism',
       'Interdisciplinary'], dtype=object)
In [18]:
category = ['Engineering', 'Business', 'Physical Sciences',
       'Law & Public Policy', 'Computers & Mathematics',
       'Industrial Arts & Consumer Services', 'Arts', 'Health',
       'Social Science', 'Biology & Life Science', 'Education',
       'Agriculture & Natural Resources', 'Humanities & Liberal Arts',
       'Psychology & Social Work', 'Communications & Journalism',
       'Interdisciplinary']
ax7 = recent_grads.plot(x='Major_category', y='Median', kind='scatter')
ax7.set_title('Major_Category vs. Median')
ax7.set_xticklabels(category,rotation=90)
Out[18]:
[Text(0, 0, 'Engineering'),
 Text(0, 0, 'Business'),
 Text(0, 0, 'Physical Sciences'),
 Text(0, 0, 'Law & Public Policy'),
 Text(0, 0, 'Computers & Mathematics'),
 Text(0, 0, 'Industrial Arts & Consumer Services'),
 Text(0, 0, 'Arts'),
 Text(0, 0, 'Health'),
 Text(0, 0, 'Social Science'),
 Text(0, 0, 'Biology & Life Science'),
 Text(0, 0, 'Education'),
 Text(0, 0, 'Agriculture & Natural Resources'),
 Text(0, 0, 'Humanities & Liberal Arts'),
 Text(0, 0, 'Psychology & Social Work'),
 Text(0, 0, 'Communications & Journalism'),
 Text(0, 0, 'Interdisciplinary')]

Question-Do students in more popular majors make more money?

Answer -

  • In Engineering Major_category, more Median Salary is observed.
  • There is no correlation between Sample_size and Unemployment_rate

Question - Do students that majored in subjects that were majority female make more money?

Answer - There is no correlation between Major_category and median salary

Question -Is there any link between the number of full-time employees and median salary?

Answer-

  • The scatter plot suggests that there is ver weak correlation between the Full_time and Median.
  • The vertical line means that the input and output values are irrelevant to each other.

Step 6 - HISTOGRAMS

Generate histograms in separate jupyter notebook cells to explore the distributions of the following columns:

  • Sample_size
  • Median
  • Employed
  • Full_time
  • ShareWomen
  • Unemployment_rate
  • Men
  • Women
In [19]:
recent_grads['Sample_size'].plot(kind='hist').set_title('Values distribution of Sample_size')
Out[19]:
Text(0.5, 1.0, 'Values distribution of Sample_size')

As per observation from generated histogram, More than 50% values for Sample_sixe category falls under 500.

In [20]:
recent_grads['Median'].plot(kind='hist').set_title('Values distribution of Median')
Out[20]:
Text(0.5, 1.0, 'Values distribution of Median')

As per observation from generated histogram, Around 50% median salary values fall in between 22000 to 42000.

In [21]:
recent_grads['Employed'].plot(kind='hist').set_title('Values distribution of Employed')
Out[21]:
Text(0.5, 1.0, 'Values distribution of Employed')

As per observation from generated histogram, More than 50% values for employed category fall in between 0 to 50000 range.

In [22]:
recent_grads['Full_time'].plot(kind='hist').set_title('Values distribution of Full_time')
Out[22]:
Text(0.5, 1.0, 'Values distribution of Full_time')

As per observation from generated histogram, More than 50% values for full_time category fall in between 0 to 50000 range.

In [23]:
recent_grads['ShareWomen'].plot(kind='hist').set_title('Values distribution of ShareWomen')
Out[23]:
Text(0.5, 1.0, 'Values distribution of ShareWomen')

As per observation from generated histogram, ShareWomen values within range of 0.2 - 0.6 have atleast freaquency of 15%.

In [24]:
recent_grads['Unemployment_rate'].plot(kind='hist').set_title('Values distribution of Unemployment_rate')
Out[24]:
Text(0.5, 1.0, 'Values distribution of Unemployment_rate')

As per observation from generated histogram, For Unemployment_rate category all values have atleast freaquency of 10%.

In [25]:
recent_grads['Men'].plot(kind='hist').set_title('Values distribution of Men')
Out[25]:
Text(0.5, 1.0, 'Values distribution of Men')

or for more ease in readibilty, we can customize the bins of histogram, shown below-

In [26]:
recent_grads['Men'].hist(bins=5).set_title('Values distribution of Men')
Out[26]:
Text(0.5, 1.0, 'Values distribution of Men')

As per observation from generated histogram, 20% values for Men category fall in range of 0 - 25000.

In [27]:
recent_grads['Women'].hist(bins=5).set_title('Values distribution of Women')
Out[27]:
Text(0.5, 1.0, 'Values distribution of Women')

As per observation from generated histogram histogram, 20% values for Women category fall in range of 0 - 50000.

Comparing Men and Women against all 172 Majors using Line Chart

Aim : To answer - Which Majors are predominantly male? Predominantly female?

In [28]:
# Comparing Men and Women against different Majors using Line Chart
# Aim : To answer - Which majors are predominantly male? Predominantly female?
# fig = plt.figure(figsize=(20,38))
fig = plt.figure(figsize=(20,100))
colors = ['red','blue' ]

plt.plot(recent_grads['Men'], recent_grads['Major'], c='red', label='Men')
plt.plot(recent_grads['Women'],recent_grads['Major'], c='blue', label='Women')

plt.legend(loc='upper left')

plt.ylabel('Majors')

plt.show()

Women are having high percentage of participation over Males in Majors.

STEP 7- Use the plots to explore the following questions:

  • What percent of majors are predominantly male? Predominantly female?
  • What's the most common median salary range?

Answers -

  • 20% values for Women category fall in range of 0 - 50000 and 20% values for Men category fall in range of 0 - 25000.
  • Females are predominant over male almost in all Majors.

  • Most Common Median Salary is22000 to 42000, which accounts to 50 % of Median Salary Values.

Step 8 - Scatter Matrix Plots

Earlier we have created individual scatter plots to visualize potential relationships between columns and histograms to visualize the distributions of individual columns.

A Scatter Matrix Plot combines both scatter plots and histograms into one grid of plots and allows us to explore potential relationships and distributions simultaneously. A scatter matrix plot consists of n by n plots on a grid, where n is the number of columns, the plots on the diagonal are histograms, and the non-diagonal plots are scatter plots.

In [29]:
from pandas.plotting import scatter_matrix
In [30]:
# To Create a 2 by 2 scatter matrix plot using the Sample_size and Median columns.
scatter_matrix(recent_grads[['Sample_size', 'Median']], figsize=(10,10))
Out[30]:
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x000001F21B5DDDC8>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x000001F21DFA1C08>],
       [<matplotlib.axes._subplots.AxesSubplot object at 0x000001F22287DE88>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x000001F21DFD5F48>]],
      dtype=object)
  • From Histogram - 50% of Median Salary Value falls in range of 22000 to 42000 and More than 50% values for Sample_sixe category falls under 500.
  • From Scatterplot -Sample_size and Median are not correlated
  • With the help of Scatter_Matrix plot, we performed two plots together.
In [31]:
# To Create a 3 by 3 scatter matrix plot using the Sample_size, Median, and Unemployment_rate columns.
scatter_matrix(recent_grads[['Sample_size', 'Median', 'Unemployment_rate']], figsize=(10,10))
Out[31]:
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x000001F21E0C16C8>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x000001F21E31E7C8>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x000001F21E117BC8>],
       [<matplotlib.axes._subplots.AxesSubplot object at 0x000001F21E1504C8>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x000001F21E187E08>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x000001F21E1C0B48>],
       [<matplotlib.axes._subplots.AxesSubplot object at 0x000001F21E1F8C48>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x000001F21E231D88>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x000001F21E23B988>]],
      dtype=object)