Python

World Happiness Report Analysis in Python: 9 Visualizations

·

Choropleth world map shading 156 countries by 2019 happiness score from 2.9 to 7.8

The World Happiness Report 2019 ranks 156 countries by self-reported life satisfaction. Each country carries one happiness score and 6 contributing factors, and this guide analyzes that dataset in Python across 9 visualizations.

The stack stays small: pandas loads and reshapes the data, Matplotlib and seaborn draw the static charts, and Folium renders the interactive world map. pywaffle builds the regional breakdowns.

Two columns in this dataset get misread in almost every published analysis. Freedom to make life choices ranks Uzbekistan first and Somalia fourteenth. Perceptions of corruption assigns Afghanistan a value of 0.025, near the bottom of all 156 countries. Neither column measures what its name suggests. This guide reads both correctly and shows the code behind each reading.

Every figure below comes from the raw CSV, recomputed at runtime.

Dataset Overview

The 2019 dataset holds 156 rows and 9 columns, one row per country. Responses come from the Gallup World Poll, which asks people to rate their own lives from 0 to 10. The file contains zero missing values, so no imputation step applies.

The exact file used for every figure in this guide is available at world-happiness-report-2019.csv, so each result can be recomputed locally.

Here is what each column holds and the range it spans.

ColumnTypeRange in this fileWhat it holds
Overall rankint1 to 156Position by happiness score, descending
Country or regionstr156 uniqueCountry name as reported by Gallup
Scorefloat2.853 to 7.769The life ladder rating on a 0 to 10 scale
GDP per capitafloat0.000 to 1.684Score points attributed to income
Social supportfloat0.000 to 1.624Score points attributed to having someone to count on
Healthy life expectancyfloat0.000 to 1.141Score points attributed to years lived in good health
Freedom to make life choicesfloat0.000 to 0.631Score points attributed to satisfaction with personal choice
Generosityfloat0.000 to 0.566Score points attributed to recent charitable donation
Perceptions of corruptionfloat0.000 to 0.453Score points attributed to trust in government and business

Finland tops the file at 7.769. South Sudan sits last at 2.853. The full spread covers 4.916 points.

The six factors are contributions, not measurements

Each factor column holds an estimated contribution to the happiness score, not a raw measurement. GDP per capita reads 1.340 for Finland, which is not dollars and not a growth rate. It is the portion of Finland’s 7.769 score that the report attributes to income.

This distinction changes how every later chart reads. A high Perceptions of corruption value means more trust, because trust adds points to the score. A low value means the report credits that country with few points from trust.

The six factors also sum to less than the score. That gap has a name and a size.

factors = [
    'GDP per capita',
    'Social support',
    'Healthy life expectancy',
    'Freedom to make life choices',
    'Generosity',
    'Perceptions of corruption'
]

df['sum_six'] = df[factors].sum(axis=1)
df['residual'] = df['Score'] - df['sum_six']

print(round(df['residual'].mean(), 3))
print(round(df['residual'].min(), 3), round(df['residual'].max(), 3))
1.88
0.184 3.05

The residual averages 1.880 points and ranges from 0.184 to 3.050. It represents Dystopia plus unexplained variance, a baseline the report adds to every country. The 2019 file omits this as a named column. Any analysis referencing a Dystopia residual column in this specific file references a column that does not exist. Earlier report years ship that column separately.

Loading the dataset

Load the CSV with pandas and confirm the shape before plotting anything.

import pandas as pd

df = pd.read_csv('2019.csv')

print(df.shape)
print(df.isna().sum().sum())

df.head(10)
(156, 9)
0

The shape confirms 156 countries and 9 columns. The null count of 0 confirms a clean file.

Overall rankCountry or regionScoreGDP per capitaSocial supportHealthy life expectancyFreedom to make life choicesGenerosityPerceptions of corruption
1Finland7.7691.3401.5870.9860.5960.1530.393
2Denmark7.6001.3831.5730.9960.5920.2520.410
3Norway7.5541.4881.5821.0280.6030.2710.341
4Iceland7.4941.3801.6241.0260.5910.3540.118
5Netherlands7.4881.3961.5220.9990.5570.3220.298
6Switzerland7.4801.4521.5261.0520.5720.2630.343
7Sweden7.3431.3871.4871.0090.5740.2670.373
8New Zealand7.3071.3031.5571.0260.5850.3300.380
9Canada7.2781.3651.5051.0390.5840.2850.308
10Austria7.2461.3761.4751.0160.5320.2440.226

Iceland ranks 4th overall while scoring 0.118 on Perceptions of corruption, a value close to the file mean of 0.111. That single row shows why reading the column as a corruption index produces wrong conclusions.

Top 10 Happiest Countries

The 10 highest-scoring countries in 2019 span 7.246 to 7.769, a range of just 0.523 points. Sort by Score and plot the result as a horizontal bar chart.

import matplotlib.pyplot as plt
import seaborn as sns

top_10 = df.sort_values(by='Score', ascending=False).head(10)

plt.figure(figsize=(10, 6))
sns.barplot(
    x='Score',
    y='Country or region',
    data=top_10,
    palette='viridis'
)
plt.title('Top 10 Happiest Countries (2019)')
plt.xlabel('Happiness Score')
plt.ylabel('Country')
plt.tight_layout()
plt.show()

Horizontal bar chart of the 10 happiest countries in 2019 led by Finland at 7.769

The ranking runs Finland, Denmark, Norway, Iceland, Netherlands, Switzerland, Sweden, New Zealand, Canada, Austria. Eight of the 10 sit in Europe. Six of those eight sit in the Nordic region.

What the top 10 share

The top 10 group posts high values on 3 of the 6 factors and mixed values on the rest.

FactorTop 10 meanTop 10 rangeFile mean
GDP per capita1.3871.303 to 1.4880.905
Social support1.5441.475 to 1.6241.209
Healthy life expectancy1.0180.986 to 1.0520.725
Freedom to make life choices0.5790.532 to 0.6030.393
Generosity0.2740.153 to 0.3540.185
Perceptions of corruption0.3190.118 to 0.4100.111

GDP per capita, social support, and healthy life expectancy all run above 1.5 times the file mean. Generosity separates the group least, at 1.48 times the mean. Finland ranks 1st overall while posting 0.153 on generosity, below the file mean of 0.185.

The spread inside the group stays narrow. Iceland at 0.118 on trust and Denmark at 0.410 sit 3.5 times apart on the same factor, in the same top 10.

Visualizing Happiness Globally

A choropleth map shades every country by its happiness score and exposes regional patterns in one frame. Building it takes 2 steps: reconciling country names against a GeoJSON boundary file, then drawing the layer with Folium.

Step 1: Prepare the data

Country names in the Gallup file differ from the names in the GeoJSON boundaries. Five renames cover the mismatches that matter.

import pandas as pd
import folium
import requests

url = 'https://raw.githubusercontent.com/python-visualization/folium/master/examples/data/world-countries.json'
geo_json_data = requests.get(url).json()

df_map = df.copy()
df_map = df_map.rename(columns={"Country or region": "Country"})

df_map = df_map.replace({
    "United States": "United States of America",
    "Tanzania": "United Republic of Tanzania",
    "Congo (Kinshasa)": "Democratic Republic of the Congo",
    "Congo (Brazzaville)": "Republic of the Congo",
    "Trinidad & Tobago": "Trinidad and Tobago"
}, regex=False)

Skipping this step leaves those countries unshaded on the finished map.

Step 2: Draw the choropleth

Folium binds the score column to the GeoJSON feature names and writes an interactive HTML file.

map_world = folium.Map(location=[20, 0], zoom_start=2, tiles="cartodbpositron")

folium.Choropleth(
    geo_data=geo_json_data,
    name='choropleth',
    data=df_map,
    columns=['Country', 'Score'],
    key_on='feature.properties.name',
    fill_color='YlGnBu',
    fill_opacity=0.7,
    line_opacity=0.2,
    legend_name='Happiness Score (2019)',
    nan_fill_color='lightgray'
).add_to(map_world)

map_world.save('world_happiness_2019_map.html')

Open world_happiness_2019_map.html in a browser to pan and zoom the result.

Regional patterns on the map

The shading breaks into three bands.

  • Above 7.0: Northern and Western Europe, Canada, Australia, and New Zealand render in the darkest blue. Eleven countries clear 7.2.
  • Below 4.5: Much of Sub-Saharan Africa, plus Afghanistan, Syria, and Yemen, render in pale yellow. Sixteen countries fall below 4.0.
  • Between 5.0 and 6.5: Most of South America, Southeast Asia, and Eastern Europe occupy the middle band. Ninety-seven of the 156 countries land between 4.5 and 6.5.

Gray areas mark countries absent from the Gallup file, including Greenland, Western Sahara, and North Korea.

Global Happiness Distribution

The 156 scores cluster tightly around the middle of the scale rather than splitting into rich and poor camps. A histogram with a kernel density estimate makes the shape explicit.

import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize=(10, 6))
sns.histplot(df['Score'], bins=20, kde=True, color='skyblue', edgecolor='black')

plt.title('Distribution of Happiness Scores (2019)', fontsize=14)
plt.xlabel('Happiness Score')
plt.ylabel('Number of Countries')
plt.tight_layout()
plt.show()

Histogram with KDE curve showing 2019 happiness scores clustering between 4.5 and 6.5

Five readings from the distribution

  • Range: Scores run from 2.853 to 7.769, a spread of 4.916 points.
  • Center: The mean sits at 5.407 and the median at 5.380, a gap of 0.027 points.
  • Bulk: Ninety-seven countries score between 4.5 and 6.5, which is 62.2 percent of the file.
  • Tails: Eleven countries clear 7.2 and 16 fall below 4.0.
  • Shape: Skewness measures +0.011, which describes a near-symmetric distribution rather than a skewed one.

The near-zero skew matters for interpretation. Many published analyses of this file describe a left-skewed distribution. Running df['Score'].skew() returns 0.011, and the mean and median differ by less than 0.03 points.

Why the distribution sets a baseline

The distribution converts any single score into a percentile. A country scoring 5.9 sounds mediocre against a 10-point ceiling. Against this file, 5.9 ranks 54th of 156, placing it in the top 35 percent.

The same logic supports threshold work later. Splitting the file at the quartiles produces defensible low, medium, and high bands, because the underlying shape is symmetric.

Factor-Wise Comparison Using Lollipop Charts

Three of the 6 factors carry no direct economic component: freedom to make life choices, generosity, and perceptions of corruption. Lollipop charts rank the top 15 countries on each one and expose results that contradict the overall ranking.

Freedom to make life choices

The top 15 on this factor include Uzbekistan at 0.631, Cambodia at 0.609, and Somalia at 0.559. Uzbekistan ranks 41st overall. Somalia ranks 112th.

import matplotlib.pyplot as plt

top_freedom = df[['Country or region', 'Freedom to make life choices']].sort_values(
    by='Freedom to make life choices', ascending=False).head(15)

plt.figure(figsize=(10, 6))
plt.hlines(y=top_freedom['Country or region'], xmin=0,
           xmax=top_freedom['Freedom to make life choices'], color='skyblue')
plt.plot(top_freedom['Freedom to make life choices'],
         top_freedom['Country or region'], 'o', color='steelblue')
plt.xlabel('Freedom to Make Life Choices')
plt.title('Top 15 Countries: Freedom to Make Life Choices (2019)')
plt.tight_layout()
plt.show()

Lollipop chart of the top 15 countries for freedom to make life choices, led by Uzbekistan and Cambodia

Reading: This column measures self-reported satisfaction with freedom of choice, taken from a single Gallup survey question. It records how people answer about their own lives. It does not measure press freedom, electoral integrity, or civil liberties. Uzbekistan and Cambodia rank high because their respondents report satisfaction with personal choice, not because either country ranks high on institutional freedom indexes.

Norway, Finland, Denmark, and Iceland also appear in the top 15, which is why the mismatch goes unnoticed. Sorting the full column surfaces it immediately.

Generosity

Myanmar leads generosity at 0.566, followed by Indonesia at 0.498 and Haiti at 0.419. Myanmar ranks 131st overall and Haiti ranks 147th.

top_generosity = df[['Country or region', 'Generosity']].sort_values(
    by='Generosity', ascending=False).head(15)

plt.figure(figsize=(10, 6))
plt.hlines(y=top_generosity['Country or region'], xmin=0,
           xmax=top_generosity['Generosity'], color='lightgreen')
plt.plot(top_generosity['Generosity'],
         top_generosity['Country or region'], 'o', color='seagreen')
plt.xlabel('Generosity')
plt.title('Top 15 Countries: Generosity (2019)')
plt.tight_layout()
plt.show()

Lollipop chart of the top 15 countries for generosity in 2019, led by Myanmar at 0.566

Reading: Generosity tracks charitable donation reported in the past month, adjusted for income. The adjustment removes the wealth effect, which is why low-income countries dominate the top of the column. Iceland at 0.354 and the United Kingdom at 0.348 are the highest-ranked wealthy entries.

Perceptions of corruption

Sorting this column ascending returns Moldova at 0.000, Bulgaria at 0.004, and Afghanistan at 0.025. Those are the countries credited with the fewest score points from institutional trust.

least_trust = df[['Country or region', 'Perceptions of corruption']].sort_values(
    by='Perceptions of corruption').head(15)

plt.figure(figsize=(10, 6))
plt.hlines(y=least_trust['Country or region'], xmin=0,
           xmax=least_trust['Perceptions of corruption'], color='orange')
plt.plot(least_trust['Perceptions of corruption'],
         least_trust['Country or region'], 'o', color='darkorange')
plt.xlabel('Perceptions of Corruption (Higher = More Trust)')
plt.title('Top 15 Countries: Lowest Trust Contribution (2019)')
plt.tight_layout()
plt.show()

Lollipop chart of the 15 lowest perceptions of corruption values in 2019, from Moldova at 0.000 to Albania at 0.027

Reading: The chart above carries the title from an earlier draft of this script, which labeled these 15 countries as the least corrupt. That reading inverts the column. In this file a higher value means more trust, because the factor adds points to the happiness score. The correlation between this column and Score is +0.386, a positive relationship.

Sorting descending returns the accurate list of high-trust countries.

most_trust = df[['Country or region', 'Score', 'Perceptions of corruption']].sort_values(
    by='Perceptions of corruption', ascending=False).head(8)
print(most_trust.to_string(index=False))
CountryScorePerceptions of corruption
Singapore6.2620.453
Rwanda3.3340.411
Denmark7.6000.410
Finland7.7690.393
New Zealand7.3070.380
Sweden7.3430.373
Switzerland7.4800.343
Norway7.5540.341

Singapore leads the column while ranking 34th overall. Rwanda sits 2nd on trust while ranking 152nd on happiness. Both results confirm that trust contributes to the score independently of the other 5 factors.

Happiness vs. GDP per Capita

GDP per capita correlates with the happiness score at 0.794, the strongest of the 6 factors. A scatter plot with a regression line shows both the trend and the countries that break it.

import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize=(10, 6))
sns.regplot(
    data=df,
    x='GDP per capita',
    y='Score',
    scatter_kws={'alpha': 0.6},
    line_kws={'color': 'red'},
    ci=None
)
plt.xlabel('GDP per Capita')
plt.ylabel('Happiness Score')
plt.title('Happiness Score vs. GDP per Capita (2019)')
plt.tight_layout()
plt.show()

Scatter plot of 2019 happiness score against GDP per capita with a red upward regression line

Three patterns in the scatter

  • High income, high score: Norway at 1.488 GDP and 7.554 Score, Switzerland at 1.452 and 7.480, Denmark at 1.383 and 7.600.
  • High income, mid score: Singapore at 1.572 GDP and 6.262 Score, United Arab Emirates at 1.503 and 6.825. Both post GDP values above Norway while scoring more than 0.7 points lower.
  • Low income, spread outcomes: Rwanda at 0.359 GDP scores 3.334. Kyrgyzstan at 0.551 GDP scores 5.261, nearly 2 points higher on comparable income.

Quantifying the relationship

Compute the Pearson correlation directly.

correlation = df['GDP per capita'].corr(df['Score'])
print(f"Correlation between GDP per capita and happiness score: {correlation:.3f}")
Correlation between GDP per capita and happiness score: 0.794

A coefficient of 0.794 explains roughly 63 percent of the variance in scores, calculated as r squared. The remaining 37 percent belongs to the other 5 factors and the residual. Income is the single strongest predictor in this file and it accounts for less than two thirds of the outcome.

Which Factors Influence Happiness the Most

A correlation heatmap ranks all 6 factors against the score in one frame. Drop the country column, compute the matrix, and annotate every cell.

import matplotlib.pyplot as plt
import seaborn as sns

numerical_df = df.drop(columns=['Country or region'])
correlation_matrix = numerical_df.corr()

plt.figure(figsize=(10, 8))
sns.heatmap(
    correlation_matrix,
    annot=True,
    cmap='coolwarm',
    fmt='.2f',
    square=True,
    linewidths=0.5,
    cbar_kws={'label': 'Correlation'}
)
plt.title('Correlation Heatmap - World Happiness Report 2019')
plt.tight_layout()
plt.show()

Seaborn correlation heatmap of World Happiness Report 2019 factors with GDP per capita at 0.79 against score

The 6 factors ranked against Score

FactorCorrelation with ScoreStrength
GDP per capita0.794Strong positive
Healthy life expectancy0.780Strong positive
Social support0.777Strong positive
Freedom to make life choices0.567Moderate positive
Perceptions of corruption0.386Weak positive
Generosity0.076Effectively none

This table yields three findings.

The top 3 factors sit within 0.017 of each other. GDP per capita at 0.794, healthy life expectancy at 0.780, and social support at 0.777 form a near-tie. Treating income as the dominant driver overstates a 0.017 gap.

Perceptions of corruption is positive, not negative. The value reads +0.386. Countries credited with more trust score higher. Reporting this factor as a negative correlation reverses the finding.

Generosity is uncorrelated with happiness. At 0.076, generosity carries almost no linear relationship to the score. It correlates more strongly with perceptions of corruption at 0.33 and with freedom at 0.27 than with the outcome itself.

The matrix also shows collinearity among the predictors. GDP per capita and healthy life expectancy correlate at 0.84, and GDP per capita and social support at 0.75. Any regression built on these columns carries multicollinearity that affects coefficient stability. The Python 2SLS Case Study: How Our Expert Helped a Student works through a related identification problem on macro data.

Component Breakdown: Waffle Charts by Region

Waffle charts split each region’s average score into the 6 component shares. The 2019 file ships no region column, so the grouping comes from a manual map covering 12 countries across 4 regions.

Step 1: Assign regions

region_map = {
    'Finland': 'Western Europe',
    'Denmark': 'Western Europe',
    'Norway': 'Western Europe',
    'Nigeria': 'Sub-Saharan Africa',
    'Kenya': 'Sub-Saharan Africa',
    'Ghana': 'Sub-Saharan Africa',
    'Brazil': 'Latin America and Caribbean',
    'Mexico': 'Latin America and Caribbean',
    'Argentina': 'Latin America and Caribbean',
    'Japan': 'East Asia',
    'South Korea': 'East Asia',
    'China': 'East Asia'
}

df['Region'] = df['Country or region'].map(region_map)
df_region = df.dropna(subset=['Region'])
print(len(df_region))
12

Three countries per region is a demonstration sample, not a regional average. Expanding region_map to all 156 countries produces figures that generalize.

Step 2: Compute component shares

components = ['GDP per capita', 'Social support', 'Healthy life expectancy',
              'Freedom to make life choices', 'Generosity', 'Perceptions of corruption']

region_means = df_region.groupby('Region')[components].mean()
region_percentages = region_means.div(region_means.sum(axis=1), axis=0).multiply(100)

Step 3: Draw the waffles

from pywaffle import Waffle
import matplotlib.pyplot as plt

regions_to_plot = ['Western Europe', 'Sub-Saharan Africa',
                   'Latin America and Caribbean', 'East Asia']

for region in regions_to_plot:
    data = region_percentages.loc[region].round().astype(int).to_dict()
    fig = plt.figure(
        FigureClass=Waffle,
        rows=5,
        values=data,
        title={'label': f'{region} - Happiness Component Breakdown', 'loc': 'center'},
        labels=[f"{k} ({v}%)" for k, v in data.items()],
        legend={'loc': 'lower left', 'bbox_to_anchor': (0, -0.4), 'ncol': 2, 'framealpha': 0},
        figsize=(10, 5)
    )
    plt.show()

Waffle chart of Western Europe happiness component breakdown across six factors

Waffle chart of Sub-Saharan Africa happiness component breakdown across six factors

Waffle chart of Latin America and Caribbean happiness component breakdown across six factors

Waffle chart of East Asia happiness component breakdown across six factors

Component shares across the 4 sample groups

Component shareWestern EuropeSub-Saharan AfricaLatin AmericaEast Asia
GDP per capita27.0%21.9%27.2%30.1%
Social support30.4%35.7%36.0%30.9%
Healthy life expectancy19.3%15.8%21.8%24.8%
Freedom11.5%14.9%11.1%9.3%
Generosity4.3%10.0%2.1%2.5%
Perceptions of corruption7.3%1.6%1.8%2.4%
Mean score7.6414.9236.3275.657

Four contrasts stand out across the sample.

  • Western Europe draws 7.3 percent of its total from institutional trust, over 4 times the share of any other group.
  • Sub-Saharan Africa draws 10.0 percent from generosity, nearly 5 times the Latin American share, while posting the lowest mean score at 4.923.
  • Latin America leans hardest on social support at 36.0 percent and least on generosity at 2.1 percent.
  • East Asia carries the highest GDP share at 30.1 percent and the lowest freedom share at 9.3 percent.

Percentage shares describe composition, not level. Sub-Saharan Africa shows the highest generosity share while its mean score trails Western Europe by 2.718 points.

Country-to-Country Comparison

A radar chart plots 5 countries across all 6 factors at once and exposes the different routes to a given score. The comparison covers Finland, the United States, India, Japan, and Brazil.

Step 1: Filter and normalize

Each factor spans a different range, so a radar chart requires normalization before plotting.

from sklearn.preprocessing import MinMaxScaler
import pandas as pd

factors = ['GDP per capita', 'Social support', 'Healthy life expectancy',
           'Freedom to make life choices', 'Generosity', 'Perceptions of corruption']

selected_countries = ['Finland', 'United States', 'India', 'Japan', 'Brazil']
df_compare = df[df['Country or region'].isin(selected_countries)][['Country or region'] + factors]
df_compare = df_compare.set_index('Country or region').loc[selected_countries]

scaler = MinMaxScaler()
df_normalized = pd.DataFrame(scaler.fit_transform(df_compare),
                             columns=factors, index=df_compare.index)

MinMaxScaler fits on these 5 rows only. Every axis reads relative to this group, not to all 156 countries. The lowest of the 5 renders as 0.0 and the highest as 1.0 on each axis.

Step 2: Plot the radar

import matplotlib.pyplot as plt
from math import pi

def plot_radar(data, countries):
    categories = list(data.columns)
    num_vars = len(categories)
    angles = [n / float(num_vars) * 2 * pi for n in range(num_vars)]
    angles += angles[:1]

    plt.figure(figsize=(8, 8))
    ax = plt.subplot(111, polar=True)

    for country in countries:
        values = data.loc[country].tolist()
        values += values[:1]
        ax.plot(angles, values, label=country)
        ax.fill(angles, values, alpha=0.1)

    ax.set_xticks(angles[:-1])
    ax.set_xticklabels(categories, size=10)
    plt.title("Country Comparison Across Happiness Components", size=14)
    plt.legend(loc='upper right', bbox_to_anchor=(1.3, 1.1))
    plt.tight_layout()
    plt.show()

plot_radar(df_normalized, selected_countries)

Radar chart comparing Finland, United States, India, Japan and Brazil across six happiness components

Reading the 5 profiles

CountryOverall rankScoreStrongest axisWeakest axis
Finland17.769Social support, freedom, trust (all 1.00)Generosity (0.40)
United States196.892GDP per capita (1.00), generosity (1.00)Trust (0.14)
Brazil326.300Social support (0.82)Freedom (0.00)
Japan585.886Healthy life expectancy (1.00)Generosity (0.00)
India1404.015Generosity (0.62)GDP, social support, health (0.00)

The comparison rests on four specifics.

  • Finland maxes 3 of the 6 axes and trails the United States on both GDP and generosity. Its raw generosity value is 0.153, below the file mean of 0.185.
  • The United States leads the group on income and giving while posting 0.128 on trust, the second lowest of the 5.
  • Japan tops healthy life expectancy at a raw 1.088, the highest value in the group, and posts the group’s lowest generosity at 0.069.
  • Brazil ranks 32nd on a GDP value of 1.004, roughly 70 percent of Japan’s, by pairing high social support with a low freedom value of 0.390.

Japan and Brazil separate by 26 rank positions on nearly identical social support values, 1.419 against 1.439. The gap comes from freedom and trust, not from support.

Conclusion

Nine visualizations across 156 countries produce 5 durable findings about the World Happiness Report 2019.

  • Income, health, and social support tie for first. Their correlations with Score run 0.794, 0.780, and 0.777, a span of 0.017.
  • Generosity carries no signal. At 0.076, the factor sits near zero against the outcome despite ranking Myanmar and Indonesia at the top.
  • Trust is a positive contributor. Perceptions of corruption correlates at +0.386, and higher values mean more trust in this encoding.
  • Freedom measures perception, not institutions. Uzbekistan, Cambodia, and Somalia all appear in the top 15 on that column.
  • The distribution is symmetric. Skewness reads +0.011, with mean 5.407 and median 5.380.

The recurring lesson concerns column semantics. Four of the 6 factors carry names that describe a concept while the values encode an estimated contribution to a score. Reading the column name instead of the column definition produced every error corrected in this guide.

The analysis extends in three directions from here. Plotly converts these static charts into hover-and-zoom figures with the same pandas input. Streamlit wraps the whole notebook into a browsable web app in under 100 lines. Expanding region_map from 12 countries to all 156 turns the waffle section from a demonstration into a real regional comparison.

For the plotting fundamentals behind every figure here, read Matplotlib in Python: Plots and Charts. To model this data instead of describing it, start with Machine Learning with Python: A Guide. For the sorting and searching work underneath large dataframe operations, see Efficient Python Algorithms Explained.

Students working through a graded version of this analysis get line-by-line support through our Python Assignment Help and Statistics Homework Help services.

python pandas matplotlib seaborn folium pywaffle data-visualization world-happiness-report
Share: X / Twitter LinkedIn

Related articles

  • AI movie recommendation system project banner with film and machine learning icons
    Machine Learning

    Build a Movie Recommendation System in Python

    Build a movie recommender in Python with content-based filtering, collaborative filtering, and a hybrid model, then evaluate it and ship it with Flask.

    Jan 27, 2025

  • Student extracting elements from a Python list on a laptop
    Python

    7 Ways to Extract Elements from a Python List

    Pull single items, slices, and filtered subsets from a Python list using indexing, slicing, comprehensions, filter, map, enumerate, and zip.

    Mar 14, 2023

  • Python developer roadmap showing language concepts, frameworks, and career steps
    Programming

    How to Become a Python Developer

    A step-by-step roadmap covering core Python concepts, libraries, frameworks, databases, testing, DevOps, and interview prep for aspiring Python developers.

    Oct 26, 2024

← All articles

Stuck on a programming assignment?

Get expert help in Java, C++, Python, JavaScript, SQL, and more. We deliver working code with a clear walkthrough so you can understand and defend it.