Tips Dataset Analysis

Exploratory analysis & visualization of the Seaborn “tips” dataset — 244 restaurant transactions

1 Average Bill by Day Bar
Avg Bill ($)Day of Week$17.68Thu$17.15Fri$20.44Sat$21.41Sun
Sunday highest ($21.41), Friday lowest ($17.15)
2 Tip % by Party Size Line
Party SizeTip %21.7%Solo16.6%215.2%314.6%414.2%515.6%6
Solo diners tip 21.7%, tables of 5 just 14.2%
3 Bill vs. Tip Amount Scatter
Tip Amount ($)Total Bill ($)$3$6$9$10$20$30$40$50r = 0.676
Strong positive correlation (r = 0.676)
4 Gender: Spend vs. Generosity Donut
64.3%MaleMale · 64.3%avg bill $20.74 · tip 15.8%Female · 35.7%avg bill $18.06 · tip 16.6%
Men spend more, but women tip higher % (16.6 vs 15.8)
5 Tip % by Smoker Status Histogram
FrequencyNon-smokerSmoker0-55-1010-1515-2020-2525-3030+Tip % of bill
Smokers spread wider, non-smokers cluster at 10-20%

Team Members

  • 125AD0041Graph 2 — Tip % by Party Size
  • 125AD0036Graph 3 — Bill vs. Tip Amount
  • 125AD0042Graph 4 — Gender Split
  • 125AD0043Graph 5 — Smoker Status
  • 125AD0059Graph 1 — Avg Bill by Day
total_billtipsexsmokerdaytimesize
16.991.01FemaleNoSunDinner2
10.341.66MaleNoSunDinner3
21.013.50MaleNoSunDinner3
n = 244 records · 7 columns
Source: Seaborn “tips” dataset · n = 244 Data Analysis & Visualization · Group Project

Fun Facts from the Data

Python Analysis Code

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

# Load the tips dataset
tips = sns.load_dataset('tips')

# 1. Average Bill by Day
avg_bill = tips.groupby('day')['total_bill'].mean()
plt.figure(figsize=(8, 5))
sns.barplot(data=tips, x='day', y='total_bill',
            order=['Thur', 'Fri', 'Sat', 'Sun'],
            ci=None, palette='Blues_d')
plt.xlabel('Day of Week')
plt.ylabel('Average Bill ($)')
plt.title('Average Total Bill by Day')
plt.show()

# 2. Tip % by Party Size
tips['tip_pct'] = (tips['tip'] / tips['total_bill']) * 100
tip_by_size = tips.groupby('size')['tip_pct'].mean()
plt.figure(figsize=(8, 5))
plt.plot(tip_by_size.index, tip_by_size.values,
        marker='o', color='#ea580c', linewidth=2.5)
plt.fill_between(tip_by_size.index, tip_by_size.values,
                 alpha=0.1, color='#ea580c')
plt.xlabel('Party Size')
plt.ylabel('Average Tip %')
plt.title('Tip Percentage by Party Size')
plt.show()

# 3. Bill vs Tip (Scatter + Correlation)
from scipy import stats
r, p = stats.pearsonr(tips['total_bill'], tips['tip'])
print(f'Correlation: r = {r:.3f}, p = {p:.2e}')
plt.figure(figsize=(8, 5))
sns.scatterplot(data=tips, x='total_bill', y='tip',
                hue='time', alpha=0.6)
sns.regplot(data=tips, x='total_bill', y='tip',
            scatter=False, color='black',
            line_kws={'linestyle': '--', 'alpha': 0.4})
plt.xlabel('Total Bill ($)')
plt.ylabel('Tip Amount ($)')
plt.title(f'Bill vs Tip (r = {r:.3f})')
plt.show()

# 4. Gender: Spend vs Generosity
gender_stats = tips.groupby('sex').agg(
    count=('total_bill', 'count'),
    avg_bill=('total_bill', 'mean'),
    avg_tip_pct=('tip_pct', 'mean')
)
print(gender_stats)
plt.figure(figsize=(6, 6))
plt.pie(gender_stats['count'],
       labels=['Male', 'Female'],
       autopct='%1.1f%%',
       colors=['#2563eb', '#ea580c'],
       wedgeprops={'width': 0.4})
plt.title('Order Distribution by Gender')
plt.show()

# 5. Tip % Distribution by Smoker Status
tips['tip_pct'] = (tips['tip'] / tips['total_bill']) * 100
bins = [0, 5, 10, 15, 20, 25, 30, 100]
labels = ['0-5', '5-10', '10-15', '15-20', '20-25', '25-30', '30+']
tips['tip_bin'] = pd.cut(tips['tip_pct'], bins=bins, labels=labels)
grouped = tips.groupby(['tip_bin', 'smoker']).size().unstack(fill_value=0)
grouped.plot(kind='bar', color=['#2563eb', '#ea580c'],
            width=0.8, figsize=(8, 5))
plt.xlabel('Tip % of Bill')
plt.ylabel('Frequency')
plt.legend(['Non-smoker', 'Smoker'], title='Smoker')
plt.title('Tip % Distribution by Smoker Status')
plt.show()