Near-Death Experiences

Tidy Tuesday for July 21st, 2026

Near-Death Experiences

Irene Morse

Setup and Introduction

Acknowledgements: I used GPT-5.5-mini to assist with some elements of this post, especially the code for generating plots.

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
nde_experiences = pd.read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/main/data/2026/2026-07-21/nde_experiences.csv')
nde_experiences.head()
entry_id gender classification country category language greyson_score post_date exp_date narrative_length ai_obe ai_unity ai_hellish ai_clinical ai_esp ai_past_lives ai_world_future ai_aliens
0 1 M NDE Soviet Union NDE english 0.0 1999-02-07T00:00:00Z NaN 7146 True True False True False False False False
1 2 F NDE United States NDE english 3.0 1999-02-07T00:00:00Z 1960-01-18T00:00:00Z 8188 True False False True False False False False
2 3 F NDE United States NDE english 17.0 NaN 1975-09-17T00:00:00Z 12889 True False False True False False False False
3 4 M NDE Vietnam NDE english 0.0 1999-02-07T00:00:00Z 1969-05-03T00:00:00Z 9449 True True False True False False False False
4 5 F NDE NaN NDE english 0.0 2008-01-13T00:00:00Z NaN 3579 False False False True False False False False

For this week’s Tidy Tuesday dataset, I’m interested in exploring the role of country and language as predictors of certain kinds of near-death experiences (NDEs). Do people from certain countries report certain types of NDEs more frequently? And are certain types of NDEs more prevalent in certain languages?

Part 1: Country Analysis

Let’s start by investigating the countries present in the data.

nde_experiences['country'].value_counts()
count
country
United States 390
Canada 28
Australia 26
France 24
England 8
... ...
Brazil 1
Kentucky 1
South Africa 1
Ukraine 1
Dominican Republic 1

64 rows × 1 columns


# check for NAs
nde_experiences['country'].isna().sum()
np.int64(8)

Based on the descriptive statistics so far, I will remove countries that have less than 10 entries, two misspelled countries, as well as the 8 NA values.

nde_experiences.shape
(589, 18)
nde_countries_raw = nde_experiences.groupby('country').filter(lambda x: len(x) >= 10)
nde_countries_raw.shape
(468, 18)
mask = ~nde_countries_raw['country'].isin(['U', 'unknown'])
nde_countries_raw = nde_countries_raw[mask]

nde_countries_raw.shape ## it appears that the misspelled countries were already removed when I removed countries by count
(468, 18)
mask = nde_countries_raw['country'].notna()
nde_countries_raw = nde_countries_raw[mask]
nde_countries_raw.shape  ## it appears that the NA values were already removed when I removed countries by count
(468, 18)

Next I will reshape the data to prepare for plotting.

nde_countries = nde_countries_raw.groupby('country').agg(
    ai_obe_count=('ai_obe', 'sum'),
    ai_unity_count=('ai_unity', 'sum'),
    ai_hellish_count=('ai_hellish', 'sum'),
    #ai_clinical_count=('ai_clinical', 'sum'),
    ai_esp_count=('ai_esp', 'sum'),
    ai_past_lives_count=('ai_past_lives', 'sum'),
    ai_world_future_count=('ai_world_future', 'sum'),
    ai_aliens_count=('ai_aliens', 'sum')
).reset_index()

nde_countries.head()
country ai_obe_count ai_unity_count ai_hellish_count ai_esp_count ai_past_lives_count ai_world_future_count ai_aliens_count
0 Australia 16 4 4 6 1 1 0
1 Canada 16 3 0 5 0 3 2
2 France 11 7 1 8 0 0 0
3 United States 232 58 30 59 16 20 2
# normalize the data because some countries just have more entries than others
normalization_vector = nde_countries_raw['country'].value_counts().sort_index().to_numpy()
print(normalization_vector)
[ 26  28  24 390]
# normalize the data because some countries just have more entries than others
numeric_cols = nde_countries.select_dtypes(include='number').columns

nde_countries[numeric_cols] = (
    nde_countries[numeric_cols]
    .div(normalization_vector, axis=0)
)

nde_countries.head()
country ai_obe_count ai_unity_count ai_hellish_count ai_esp_count ai_past_lives_count ai_world_future_count ai_aliens_count
0 Australia 0.615385 0.153846 0.153846 0.230769 0.038462 0.038462 0.000000
1 Canada 0.571429 0.107143 0.000000 0.178571 0.000000 0.107143 0.071429
2 France 0.458333 0.291667 0.041667 0.333333 0.000000 0.000000 0.000000
3 United States 0.594872 0.148718 0.076923 0.151282 0.041026 0.051282 0.005128

Now let’s plot!

cols = [
    'ai_obe_count',
    'ai_unity_count',
    'ai_hellish_count',
    #'ai_clinical_count',
    'ai_esp_count',
    'ai_past_lives_count',
    'ai_world_future_count',
    'ai_aliens_count'
]

heatmap_data = nde_countries.set_index('country')[cols]
col_order = heatmap_data.mean().sort_values(ascending=False).index
heatmap_data = heatmap_data[col_order]

# Clean column names for display
heatmap_data.columns = (
    heatmap_data.columns
    .str.replace('ai_', '')
    .str.replace('_count', '')
    #.str.replace('_', ' ')
    #.str.title()
)

plt.figure(figsize=(10, 8))

sns.heatmap(
    heatmap_data,
    annot=True,
    fmt='g',
    cmap='viridis'
)

plt.xlabel('Experience Type')
plt.xticks(rotation=45, ha='right', fontsize=10)
plt.ylabel('Country')
plt.tight_layout()
plt.show()

png

Based on this heatmap, it looks like out-of-body experiences are the most freqently reported feature of NDEs across all countries, followed by extrasensory perception. Interestingly, the NDEs of French people exhibit increased variation in types of experiences when compared to those of Australians, Canadans, and Americans. French NDEs were less skewed toward out-of-body experiences and were more likely to include elements of extrasensory perception and feelings of unity or oneness.

Part 2: Language Analysis

Let’s again start with some descriptive analysis.

nde_experiences['language'].value_counts()
count
language
english 549
fr 18
es 5
ar 3
sv 2
french 2
español 2
nl 2
français 1
id 1
portuguese 1
spanish 1
german 1
nederlands 1


nde_experiences['language'].isna().sum()
np.int64(0)

Luckily there are no NA values in the language column! But we still need to clean up the language entries a bit.

# recode certain language values
nde_languages_raw = nde_experiences.copy()
nde_languages_raw['language'] = nde_experiences['language'].replace({
    'fr': 'french',
    'es': 'spanish',
    'ar': 'arabic',
    'sv': 'swedish',
    'español': 'spanish',
    'nl': 'dutch',
    'français': 'french',
    'id': 'indonesian',
    'nederlands': 'dutch'
})
nde_languages_raw['language'].value_counts()  ## much better!
count
language
english 549
french 21
spanish 8
dutch 3
arabic 3
swedish 2
indonesian 1
portuguese 1
german 1


nde_languages_raw.shape
(589, 18)
# remove languages that have less than 5 instances
nde_languages_raw = nde_languages_raw.groupby('language').filter(lambda x: len(x) >= 5)
nde_languages_raw.shape  ## only 3 languages removed
(578, 18)

Just as with the country analysis, I will reshape the data to facilitate plotting.

nde_languages = nde_languages_raw.groupby('language').agg(
    ai_obe_count=('ai_obe', 'sum'),
    ai_unity_count=('ai_unity', 'sum'),
    ai_hellish_count=('ai_hellish', 'sum'),
    #ai_clinical_count=('ai_clinical', 'sum'),
    ai_esp_count=('ai_esp', 'sum'),
    ai_past_lives_count=('ai_past_lives', 'sum'),
    ai_world_future_count=('ai_world_future', 'sum'),
    ai_aliens_count=('ai_aliens', 'sum')
).reset_index()

nde_languages.head()
language ai_obe_count ai_unity_count ai_hellish_count ai_esp_count ai_past_lives_count ai_world_future_count ai_aliens_count
0 english 318 89 42 84 18 26 5
1 french 11 4 1 5 0 1 0
2 spanish 3 1 2 0 0 0 0
# normalize the data because some languages just have more entries than others
normalization_vector = nde_languages_raw['language'].value_counts().sort_index().to_numpy()
print(normalization_vector)
[549  21   8]
# normalize the data because some languages just have more entries than others
numeric_cols = nde_languages.select_dtypes(include='number').columns

nde_languages[numeric_cols] = (
    nde_languages[numeric_cols]
    .div(normalization_vector, axis=0)
)

nde_languages.head()
language ai_obe_count ai_unity_count ai_hellish_count ai_esp_count ai_past_lives_count ai_world_future_count ai_aliens_count
0 english 0.579235 0.162113 0.076503 0.153005 0.032787 0.047359 0.009107
1 french 0.523810 0.190476 0.047619 0.238095 0.000000 0.047619 0.000000
2 spanish 0.375000 0.125000 0.250000 0.000000 0.000000 0.000000 0.000000

Ready to plot!

cols = [
    'ai_obe_count',
    'ai_unity_count',
    'ai_hellish_count',
    #'ai_clinical_count',
    'ai_esp_count',
    'ai_past_lives_count',
    'ai_world_future_count',
    'ai_aliens_count'
]

heatmap_data = nde_languages.set_index('language')[cols]
col_order = heatmap_data.mean().sort_values(ascending=False).index
heatmap_data = heatmap_data[col_order]

# Clean column names for display
heatmap_data.columns = (
    heatmap_data.columns
    .str.replace('ai_', '')
    .str.replace('_count', '')
    #.str.replace('_', ' ')
    #.str.title()
)

plt.figure(figsize=(10, 8))

sns.heatmap(
    heatmap_data,
    annot=True,
    fmt='g',
    cmap='viridis'
)

plt.xlabel('Experience Type')
plt.xticks(rotation=45, ha='right', fontsize=10)
plt.ylabel('Language')
plt.tight_layout()
plt.show()

png

Just like with the country analysis, out-of-body experiences are the most common feature of all NDE narratives. In this langauge analysis, French and Spanish exhibit more variation than English. It is particularly interesting that Spanish narratives are significantly more likely to include distressing or hellish imagery.

Part 3: Over-Time Analysis of “Hellish” NDEs

The analysis thus far has prompted me to consider one new question: How have “hellish” NDEs changed over time? Thanks to Pew’s survey research, we know that the number of Americans identifying as Christian has decreased over time, and Europe has followed similar trends.

pew.png

Based on these trends, I predict that hellish NDEs will have decreased over time, but let’s check in out!

# extract year from date of NDE
nde_experiences['exp_date'] = pd.to_datetime(nde_experiences['exp_date'])
nde_experiences['year'] = nde_experiences['exp_date'].dt.year
mask = nde_experiences['year'].notna()
nde_experiences_time = nde_experiences[mask]
print(nde_experiences.shape)
print(nde_experiences_time.shape)  ## removed 76 NA values
(589, 19)
(513, 19)
nde_experiences_time = nde_experiences_time.groupby('year').agg(
    ai_hellish_count=('ai_hellish', 'sum')
).reset_index()

nde_experiences_time.describe()
year ai_hellish_count
count 67.000000 67.000000
mean 1981.179104 0.537313
std 21.085630 1.004963
min 1936.000000 0.000000
25% 1964.500000 0.000000
50% 1981.000000 0.000000
75% 1997.500000 1.000000
max 2024.000000 5.000000
plt.figure(figsize=(10, 5))

# base scatterplot
plt.plot(nde_experiences_time['year'], nde_experiences_time['ai_hellish_count'], marker='o')

# Fit quadratic polynomial
coeffs = np.polyfit(nde_experiences_time['year'], nde_experiences_time['ai_hellish_count'], 2)
poly = np.poly1d(coeffs)

# Create smooth x values for plotting the curve
x_fit = np.linspace(nde_experiences_time['year'].min(), nde_experiences_time['year'].max(), 300)
y_fit = poly(x_fit)

# Plot quadratic fit
plt.plot(x_fit, y_fit, color='purple', linestyle='--',
         label='Quadratic fit')

plt.xlabel('Year')
plt.ylabel('Hellish Count')
plt.title('Hellish NDEs - Frequency Over Time')

plt.grid(True)
plt.tight_layout()

plt.show()

png

So this result is pretty weird and unexpected! Hellish NDEs do not appear to consistently increase or decrease, though there is a surprising cluster of hellish NDEs around the year 2000. Adding a quadratic model line indicates a gradual increase over time of hellish NDEs, though with diminishing returns.

I want to double check that the surprising peaks in the graph above are not due to there simply being more data for certain years, so I will now normalize the yearly counts (as I did with the previous analyses) and re-plot.

# normalize the data because some years just have more entries than others
normalization_vector = nde_experiences['year'].value_counts().sort_index().to_numpy()
print(normalization_vector)
[ 1  1  1  2  1  2  2  4  1  4  3  1  2  3  6  4  5  4  2  7  7  7  6  7
 11  6 15  8  9 11  9 12 12 16  6  9  7  9  7 10  9 10 19 12 14  5 11 14
 14 21 20 14 16 23 23 16 15  2  1  4  2  1  1  1  2  1  2]
# normalize the data because some years just have more entries than others
nde_experiences_time['ai_hellish_prop'] = nde_experiences_time['ai_hellish_count'] / normalization_vector
plt.figure(figsize=(10, 5))

# base scatterplot
plt.plot(nde_experiences_time['year'], nde_experiences_time['ai_hellish_prop'], marker='o')

# Fit quadratic polynomial
coeffs = np.polyfit(nde_experiences_time['year'], nde_experiences_time['ai_hellish_prop'], 2)
poly = np.poly1d(coeffs)

# Create smooth x values for plotting the curve
x_fit = np.linspace(nde_experiences_time['year'].min(), nde_experiences_time['year'].max(), 300)
y_fit = poly(x_fit)

# Plot quadratic fit
plt.plot(x_fit, y_fit, color='purple', linestyle='--',
         label='Quadratic fit')

plt.xlabel('Year')
plt.ylabel('Hellish Proportion')
plt.title('Hellish NDEs - Proportion Over Time')

plt.grid(True)
plt.tight_layout()

plt.show()

png

This final graph does indeed show that the peaks around the year 2000 had less to do with there being more hellish NDEs and more to do with there being more NDEs in general. Adding the quadratic model line indicates a steady increase in hellish NDEs over time, solidly contradicting my previous prediction!

Conclusion

It turns out that country and language are not very good predictors of NDE types. This is partly because there is a lack of variation in types of NDEs, with out-of-body experiences by far the most common type of NDE, consistently followed by extrasensory perception and feelings of unity or oneness. It is also because there is a paucity of data for countries other than Australia, Canada, France, and the US, as well as for languages other than English, French, and Spanish. Therefore to answer these questions better requires a more robust and inclusive dataset on NDEs.

That being said, I did discover that, contrary to my expectations, hellish NDEs have increased over time! This is a big surprising given the decline in religiosity over time, so further investigation of (a) what exactly comprisises a “hellish” NDE and (b) why these types of experiences are on the rise is certainly warranted.




Enjoy Reading This Article?

Here are some more articles you might like to read next: