Welcome to the Sleep and Wellness Dashboard, an interactive tool that provides insights into how lifestyle factors, body metrics, and sleep disorders correlate with sleep quality. Through a series of visualizations, this dashboard highlights the connections between sleep duration, stress levels, daily physical activity, and Body Mass Index (BMI) in relation to sleep disorders.
The dataset used as the foundation of this dashboard encompasses a comprehensive range of variables related to sleep health and lifestyle habits. It includes metrics such as sleep duration, quality of sleep, stress levels, daily step count, and BMI categories, alongside indications of common sleep disorders like insomnia and sleep apnea. This dataset enables a multifaceted look at sleep trends across different populations, offering valuable insights into the interplay between physical activity, body composition, stress, and sleep quality.
Exploring the Sleep and Wellness Dashboard reveals that stress negatively impacts sleep quality, normal BMI is associated with longer sleep duration, and the absence of sleep disorders typically correlates with higher daily activity levels. Additionally, there is significant variability in sleep duration among those with sleep disorders, especially among individuals with insomnia. These insights illustrate the intricate connections between lifestyle choices, physical health, and sleep.
This chart is a correlation heatmap that displays the relationships between various sleep, health, and lifestyle variables. The colors represent the strength and direction of the correlation: red shades indicate positive correlations, blue shades indicate negative correlations, and the intensity of the color signifies the strength of the correlation. For instance, there is a very strong negative correlation between stress level and sleep quality. Conversely, sleep duration and quality of sleep show a strong positive correlation with each other. Age shows a moderate positive correlation with sleep duration. The numerical values within each cell provide the exact correlation coefficient, with 1 being a perfect positive correlation and -1 a perfect negative correlation. Values close to 0 suggest no correlation.
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
# Load the dataset
filepath = "C:/Users/themi/OneDrive/Documents/DS736/Sleep_health_and_lifestyle_dataset.csv"
dataset = pd.read_csv(filepath)
# Selecting numeric columns for correlation
numeric_cols = ['Age', 'Sleep Duration', 'Quality of Sleep', 'Physical Activity Level', 'Stress Level', 'Heart Rate', 'Daily Steps']
numeric_df = dataset[numeric_cols]
# Calculate correlation matrix
corr_matrix = numeric_df.corr()
# Visualization 1
# Create a heatmap
plt.figure(figsize=(12, 12))
ax = sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0, annot_kws={"size": 10})
# Invert y-axis to have the first row at the top
ax.invert_yaxis()
# Title the chart
plt.title('Correlation Heatmap of Sleep, Health, and Lifestyle Variables', fontsize = 14)
# Rotate x-axis and y-axis labels
ax.set_xticklabels(ax.get_xmajorticklabels(), fontsize = 10, rotation=45)
ax.set_yticklabels(ax.get_ymajorticklabels(), fontsize = 10, rotation=45)
# Access the colorbar
cbar = ax.collections[0].colorbar
# Define the max value for the colorbar
max_count = np.max(corr_matrix.to_numpy())
# Create colorbar ticks and labels
my_colorbar_ticks = [*range(0, int(max_count), 5000)]
cbar.set_ticks(my_colorbar_ticks)
my_colorbar_tick_labels = ['{:,}'.format(each) for each in my_colorbar_ticks]
cbar.set_ticklabels(my_colorbar_tick_labels)
# Set the colorbar label
cbar.set_label('Correlation Level', rotation=270, fontsize=14, color='black', labelpad=20)
# Show the plot
plt.show()
This box plot compares the sleep duration among individuals with different sleep disorders. The categories include those with no sleep disorder, those with sleep apnea, and those with insomnia. The y-axis represents sleep duration in hours. Individuals without a sleep disorder appear to have a median sleep duration around 7.5 hours, with a relatively small interquartile range, indicating less variability in sleep duration. Those with sleep apnea have a higher median sleep duration, close to 8 hours, but with a larger interquartile range, suggesting more variability. Insomnia sufferers have a much lower median sleep duration of just over 6 hours and also show a considerable spread in the data, as indicated by the interquartile range and outliers. Outliers are represented by diamond shapes, and are particularly numerous and spread out for those with insomnia, indicating that sleep duration among insomnia sufferers varies widely.
# Visualization 2
# Create a boxplot
plt.figure(figsize=(10, 6))
sns.boxplot(x='Sleep Disorder', y='Sleep Duration', data=dataset)
# Title and label the chart
plt.title('Sleep Duration by Sleep Disorder', fontsize=14)
plt.ylabel('Hours of Sleep', fontsize=12)
plt.xlabel('Sleep Disorder Type', fontsize=12)
# Customize ticks and palette
tick_size = 10
ax.tick_params(axis='both', labelsize=tick_size)
sns.boxplot(x='Sleep Disorder', y='Sleep Duration', data=dataset, palette='Set2')
plt.show()
The bar chart shows average sleep duration across different BMI categories: Normal, Obese, and Overweight. Individuals with a normal BMI have the highest average sleep duration at 7.36 hours, followed by obese individuals at 6.96 hours, and overweight individuals sleep the least on average at 6.77 hours. The bars represent the average hours of sleep, and the numbers above each bar denote the exact average for that category.
# Visualization 3
# Calculating average sleep duration by BMI Category
avg_sleep_by_BMI = dataset.groupby('BMI Category')['Sleep Duration'].mean().reset_index()
# Sorting the results for better visualization
avg_sleep_by_BMI_sorted = avg_sleep_by_BMI.sort_values('Sleep Duration', ascending=False)
# Combine "Normal" and "Normal Weight" into a single category:
avg_sleep_by_BMI_sorted['BMI Category'] = avg_sleep_by_BMI_sorted['BMI Category'].replace({'Normal Weight': 'Normal'})
# Create a bar chart
plt.figure(figsize=(10, 6))
barplot = sns.barplot(x='BMI Category', y='Sleep Duration', data=avg_sleep_by_BMI_sorted, palette='coolwarm')
# Add labels to each category
for p in barplot.patches:
barplot.annotate(format(p.get_height(), '.2f'),
(p.get_x() + p.get_width() / 2., p.get_height()), ha = 'center', va = 'center', xytext = (0, 7),
textcoords = 'offset points')
# Title and label the chart
plt.title('Average Sleep Duration by BMI Category', fontsize=14)
plt.ylabel('Average Sleep Duration', fontsize=12)
plt.xlabel('BMI Category', fontsize=12)
plt.show()
The donut chart illustrates the distribution of daily steps for individuals with different sleep disorders. The largest portion, 58.87% (1,500,800 steps), represents those without a sleep disorder. Individuals with sleep apnea account for 23.31% (594,300 steps) of the total daily steps, while those with insomnia contribute 17.82% (454,400 steps). The numbers in parentheses indicate the total steps taken by individuals in each category, and the numbers outside the parentheses show the percentage of the total steps. The ‘n’ value denotes the number of individuals in each category.
# Visualization 4
# Summing up the daily steps for each sleep disorder and counting the occurrences
category_agg = dataset.groupby('Sleep Disorder').agg({'Daily Steps': 'sum', 'Sleep Disorder': 'size'}).rename(columns={'Sleep Disorder': 'Participant Count'}).reset_index()
# Calculate the total for the central text
total_steps = category_agg['Daily Steps'].sum()
# Create a figure for the donut chart
fig, ax = plt.subplots(figsize=(8, 8))
# Generate a color for each unique category
unique_categories = category_agg['Sleep Disorder'].nunique()
colors = plt.cm.tab20b(np.linspace(0, 1, unique_categories))
# Create the pie chart
wedges, texts, autotexts = ax.pie(
category_agg['Daily Steps'],
labels=[f"{disorder} (n={count})" for disorder, count in zip(category_agg['Sleep Disorder'], category_agg['Participant Count'])],
colors=colors,
autopct=lambda p: '{:.2f}%\n({:.0f} steps)'.format(p, (p/100) * total_steps),
startangle=90,
pctdistance=0.85,
labeldistance=1.1,
wedgeprops=dict(width=0.3, edgecolor='w')
)
# Customize text size for labels
plt.setp(texts, size=12)
## [None, None, None, None, None, None]
plt.setp(autotexts, size=12, weight="bold", color="white")
## [None, None, None, None, None, None, None, None, None, None, None, None]
# Draw a circle at the center to create the donut hole
centre_circle = plt.Circle((0, 0), 0.5, fc='white')
fig.gca().add_artist(centre_circle)
# Add the title of the donut chart
plt.title('Total Daily Steps by Sleep Disorder', fontsize=14)
# Hide the y-axis label
ax.yaxis.set_visible(False)
# Ensure the chart is drawn as a circle
ax.axis('equal')
## (-1.0999999777191496, 1.0999995553153394, -1.0999989697047796, 1.099999950938323)
# Apply layout to optimize spacing
plt.tight_layout()
# Display the plot
plt.show()
The scatter plot shows the relationship between the quality of sleep and stress levels. The quality of sleep is measured on the y-axis, and stress levels are on the x-axis. Each dot represents a data point, and the size of the dot indicates the density of observations at that point, with larger dots showing higher density. Most data points seem to be concentrated around the middle range of both quality of sleep and stress levels, with a few outliers. There appears to be a cluster of data points with high-quality sleep at lower stress levels, whereas higher stress levels show a more spread out and lower quality of sleep. The trend in the scatter plot suggests that as stress levels increase, the quality of sleep tends to decrease.
# Visualization 5
import numpy as np
from scipy.stats import gaussian_kde
# Set the two variables
x = dataset['Stress Level']
y = dataset['Quality of Sleep']
# Calculate the point density
xy = np.vstack([x,y])
z = gaussian_kde(xy)(xy)
# Sort the points by density, so that the densest points are plotted last
idx = z.argsort()
x, y, z = x[idx], y[idx], z[idx]
# Create the scatter plot
fig, ax = plt.subplots()
scatter = ax.scatter(x, y, s=100*z+50, edgecolor='grey', color='blue')
# Set the title and labels
ax.set_title('Quality of Sleep vs. Stress Level with Density Indicated by Size', fontsize=14)
ax.set_xlabel('Stress Level', fontsize=12)
ax.set_ylabel('Quality of Sleep', fontsize=12)
# Show the plot
plt.show()
The Sleep and Wellness Dashboard showcases the dynamics between lifestyle, physical health, and sleep. Key takeaways include the detrimental effect of stress on sleep quality, the beneficial link between a normal BMI and longer sleep, and the contrast in activity levels in individuals with and without sleep disorders. This data-driven approach provides a holistic view, supporting the importance of managing stress, maintaining a healthy weight, and staying active for better sleep health.