【数据可视化】3000名烟酒成瘾者数据深度可视化分析(Python + PyEcharts 炫酷暗黑风)

🧑 博主简介:曾任某智慧城市类企业算法总监,CSDN / 稀土掘金 等平台人工智能领域优质创作者。
目前在美国市场的物流公司从事高级算法工程师一职,深耕人工智能领域,精通python数据挖掘、可视化、机器学习等,发表过AI相关的专利并多次在AI类比赛中获奖。


引言

在当今社会,烟酒成瘾问题日益严重,影响着无数人的健康和生活质量。通过对3000名烟酒成瘾者的详细数据进行分析,我们可以从多个维度深入了解成瘾者的特征和行为模式。本文将利用 Python 和 PyEcharts,以炫酷的暗黑风格可视化这些数据,揭示隐藏在数字背后的故事。


二、 技术栈

  • Python 3.9+
  • PyEcharts(支持暗黑主题、动态交互)
  • Pandas(数据处理)
  • Jupyter Notebook(演示)

三、数据集预览

字段名 含义
age 年龄
gender 性别
country 国家
education_level 教育水平
employment_status 就业状态
annual_income_usd 年收入(美元)
smokes_per_day 每日吸烟支数
drinks_per_week 每周饮酒次数
age_started_smoking 开始吸烟年龄
age_started_drinking 开始饮酒年龄
attempts_to_quit_smoking 尝试戒烟次数
attempts_to_quit_drinking 尝试戒酒次数
has_health_issues 是否有健康问题
mental_health_status 心理健康状态
exercise_frequency 锻炼频率
diet_quality 饮食质量
sleep_hours 睡眠时间
bmi BMI指数

四、安装依赖

复制代码
pip install pyecharts pandas numpy

五、数据可视化完整代码(可直接运行)

加载需要的处理库和简单的数据清洗:

python 复制代码
import pandas as pd
import numpy as np
from pyecharts.charts import *
from pyecharts.globals import ThemeType, SymbolType
import warnings, math, random
from pyecharts.commons.utils import JsCode
from pyecharts import options as opts


warnings.filterwarnings('ignore')

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

# 1. 关键字段清洗
df['has_health_issues'] = df['has_health_issues'].astype(int)
df['age_group'] = pd.cut(df['age'], bins=[0,25,35,45,55,100],
                         labels=['≤25','26-35','36-45','46-55','55+'])
df['income_group'] = pd.qcut(df['annual_income_usd'], q=4,
                             labels=['低收入','中低收入','中高收入','高收入'])

5.1 年龄分布直方图(平滑密度图)

less 复制代码
# 1. 年龄分布直方图(平滑密度图)
def age_distribution():
    return (
        Line(init_opts=opts.InitOpts(width="900px", height="500px", theme=theme))
        .add_xaxis(df['age'].value_counts().sort_index().index.tolist())
        .add_yaxis(
            "年龄分布",
            df['age'].value_counts().sort_index().values.tolist(),
            is_smooth=True,
            linestyle_opts=opts.LineStyleOpts(width=4, color="#00f5ff"),
            itemstyle_opts=opts.ItemStyleOpts(color="#00f5ff")
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(title="1. 年龄分布(平滑密度图)", subtitle="总人数:3000人"),
            xaxis_opts=opts.AxisOpts(name="年龄"),
            yaxis_opts=opts.AxisOpts(name="人数"),
            tooltip_opts=opts.TooltipOpts(trigger="axis", axis_pointer_type="cross")
        )
    )

数据中统计的人员年纪在30-80岁之前,吸烟和饮酒成瘾与年纪分布看不出什么规律;

5.2 性别分布玫瑰图

ini 复制代码
# 2. 性别分布玫瑰图
def gender_distribution():
    gender_counts = df['gender'].value_counts()
    return (
        Pie(init_opts=opts.InitOpts(width="500px", height="400px", theme=theme))
        .add(
            "",
            [list(z) for z in zip(gender_counts.index, gender_counts.values)],
            radius=["20%", "75%"],
            rosetype="radius",
            label_opts=opts.LabelOpts(is_show=True, formatter="{b}: {c} ({d}%)")
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(title="2. 性别分布(玫瑰图)")
        )
    )

数据中成瘾的人员,男女比例相当,女性还略高于男性,可以看出吸烟和饮酒成瘾的并不是男的居多;

5.3 国家分布

ini 复制代码
# 3. 国家分布
def country_map_distribution():
    country_counts = df['country'].value_counts().reset_index()
    country_counts.columns = ['country', 'count']

    world_map = (
        Map(init_opts=opts.InitOpts(theme=dark_theme, width="100%", height="700px"))
        .add(
            series_name="成瘾者数量",
            data_pair=[list(z) for z in zip(country_counts['country'].tolist(), country_counts['count'].tolist())],
            maptype="world",
            is_map_symbol_show=False,
            label_opts=opts.LabelOpts(is_show=False),
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(title="全球成瘾者分布"),
            visualmap_opts=opts.VisualMapOpts(
                max_=max(country_counts['count']),
                min_=1,
                is_calculable=True,
                range_color=['#313695', '#4575b4', '#74add1', '#abd9e9', '#e0f3f8', '#ffffbf', '#fee090', '#fdae61', '#f46d43', '#d73027', '#a50026'],
                textstyle_opts=opts.TextStyleOpts(color="#fff")
            ),
            tooltip_opts=opts.TooltipOpts(
                formatter=JsCode(
                    """function(params) {
                        return params.name + ': ' + params.value + '人';
                    }"""
                )
            )
        )
    )

从图上可以看出,颜色越深的国家,吸烟饮酒成瘾的人数越多,其中Saudi Arabia占28人。

5.4 教育水平分布饼图

ini 复制代码
# 4. 教育水平分布饼图
def education_distribution():
    edu_counts = df['education_level'].value_counts()
    return (
        Pie(init_opts=opts.InitOpts(width="500px", height="400px", theme=theme))
        .add(
            "",
            [list(z) for z in zip(edu_counts.index, edu_counts.values)],
            radius=["30%", "70%"],
            label_opts=opts.LabelOpts(is_show=True)
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(title="4. 教育水平分布")
        )
    )

吸烟饮酒成瘾与学历几乎无关,可能不同学历的人有不同烦恼。

5.5 就业状况分布饼图

ini 复制代码
# 5. 就业状况分布饼图
def employment_distribution():
    emp_counts = df['employment_status'].value_counts()
    return (
        Pie(init_opts=opts.InitOpts(width="500px", height="400px", theme=theme))
        .add(
            "",
            [list(z) for z in zip(emp_counts.index, emp_counts.values)],
            radius=["30%", "70%"],
            label_opts=opts.LabelOpts(is_show=True)
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(title="5. 就业状况分布")
        )
    )

从图中可以看出就业状况与是否吸烟饮酒成瘾的关系也并不大。

5.6 收入 vs 吸烟/饮酒散点图(按性别着色)

less 复制代码
# 6. 收入 vs 吸烟/饮酒散点图(按性别着色)
def income_vs_addiction():
    scatter = (
        Scatter(init_opts=opts.InitOpts(width="900px", height="500px", theme=theme))
        .add_xaxis(df['smokes_per_day'].tolist())
        .add_yaxis(
            "Male",
            df[df['gender'] == 'Male'][['smokes_per_day', 'annual_income_usd']].values.tolist(),
            symbol_size=8,
            color="#00ffcc"
        )
        .add_yaxis(
            "Female",
            df[df['gender'] == 'Female'][['smokes_per_day', 'annual_income_usd']].values.tolist(),
            symbol_size=8,
            color="#ff00ff"
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(title="6. 吸烟量 vs 年收入(按性别着色)"),
            xaxis_opts=opts.AxisOpts(name="每日吸烟支数"),
            yaxis_opts=opts.AxisOpts(name="年收入(美元)")
        )
    )
    return scatter

5.7 开始吸烟和饮酒年龄的箱线图

less 复制代码
# 7. 开始吸烟和饮酒年龄的箱线图
def age_started_boxplot():
    return (
        Boxplot(init_opts=opts.InitOpts(width="600px", height="400px", theme=theme))
        .add_xaxis(["开始吸烟年龄", "开始饮酒年龄"])
        .add_yaxis("", [df['age_started_smoking'].dropna().tolist(), df['age_started_drinking'].dropna().tolist()])
        .set_global_opts(
            title_opts=opts.TitleOpts(title="7. 开始吸烟 vs 饮酒年龄分布(箱线图)")
        )
    )

5.8 尝试戒烟/戒酒次数直方图

less 复制代码
# 8. 尝试戒烟/戒酒次数直方图
def quit_attempts_histogram():
    return (
        Bar(init_opts=opts.InitOpts(width="900px", height="500px", theme=theme))
        .add_xaxis(df['attempts_to_quit_smoking'].value_counts().sort_index().index.tolist())
        .add_yaxis("尝试戒烟次数", df['attempts_to_quit_smoking'].value_counts().sort_index().values.tolist(), color="#ffcc00")
        .set_global_opts(
            title_opts=opts.TitleOpts(title="8. 尝试戒烟次数分布"),
            xaxis_opts=opts.AxisOpts(name="尝试次数"),
            yaxis_opts=opts.AxisOpts(name="人数")
        )
    )

5.9 健康问题 vs 吸烟/饮酒量(分组箱线图)

less 复制代码
# 9. 健康问题 vs 吸烟/饮酒量(分组箱线图)
def health_vs_addiction():
    df['has_health_issues'] = df['has_health_issues'].astype(str)
    return (
        Boxplot(init_opts=opts.InitOpts(width="800px", height="500px", theme=theme))
        .add_xaxis(["无健康问题", "有健康问题"])
        .add_yaxis("每日吸烟量", [
            df[df['has_health_issues'] == 'False']['smokes_per_day'].dropna().tolist(),
            df[df['has_health_issues'] == 'True']['smokes_per_day'].dropna().tolist()
        ])
        .set_global_opts(
            title_opts=opts.TitleOpts(title="9. 健康问题 vs 每日吸烟量")
        )
    )

5.10 心理健康状态分布饼图

ini 复制代码
# 10. 心理健康状态分布饼图
def mental_health_pie():
    mh_counts = df['mental_health_status'].value_counts()
    return (
        Pie(init_opts=opts.InitOpts(width="500px", height="400px", theme=theme))
        .add(
            "",
            [list(z) for z in zip(mh_counts.index, mh_counts.values)],
            radius=["30%", "70%"],
            label_opts=opts.LabelOpts(is_show=True)
        )
        .set_global_opts(
            title_opts=opts.TitleOpts(title="10. 心理健康状态分布")
        )
    )

5.11 BMI 与吸烟量散点图

less 复制代码
# 11. BMI 与吸烟量散点图
def bmi_vs_smoking():
    return (
        Scatter(init_opts=opts.InitOpts(width="900px", height="500px", theme=theme))
        .add_xaxis(df['bmi'].tolist())
        .add_yaxis("吸烟量", df['smokes_per_day'].tolist(), symbol_size=6, color="#ff6b6b")
        .set_global_opts(
            title_opts=opts.TitleOpts(title="11. BMI vs 每日吸烟量"),
            xaxis_opts=opts.AxisOpts(name="BMI"),
            yaxis_opts=opts.AxisOpts(name="每日吸烟支数")
        )
    )

5.12 吸烟与饮酒的双玫瑰图

ini 复制代码
def dual_rose():
    smoke_bins = pd.cut(df['smokes_per_day'], bins=[-1,5,10,20,999],
                        labels=['轻','中','重','极重'])
    drink_bins = pd.cut(df['drinks_per_week'], bins=[-1,2,7,14,999],
                        labels=['轻','中','重','极重'])
    cross = pd.crosstab(smoke_bins, drink_bins)
    c = (
        Pie(init_opts=opts.InitOpts(theme=ThemeType.DARK,
                                    width='1000px', height='600px'))
        .add("吸烟等级", [list(z) for z in cross.sum(axis=1).items()],
             radius=['25%', '45%'], center=['25%', '50%'], rosetype='radius')
        .add("饮酒等级", [list(z) for z in cross.sum(axis=0).items()],
             radius=['25%', '45%'], center=['75%', '50%'], rosetype='radius')
        .set_series_opts(label_opts=opts.LabelOpts(color='#fff',
                                                   formatter="{b}: {d}%"))
        .set_global_opts(title_opts=opts.TitleOpts(title="烟枪 vs 酒鬼",
                                                   subtitle="玫瑰双环"),
                         legend_opts=opts.LegendOpts(textstyle_opts=opts.TextStyleOpts(color='#fff')))
    )
    return c

5.13 多维度雷达图

ini 复制代码
def create_radar_chart(age_group):
    group_data = df[df['age_group'] == age_group].mean()
    
    data = [
        group_data['smokes_per_day'],
        group_data['drinks_per_week'],
        group_data['bmi'],
        group_data['sleep_hours'],
        group_data['attempts_to_quit_smoking'],
        group_data['children_count']
    ]
    
    return data
## 3、 雷达图
def rader_distribution():

    df['has_health_issues'] = df['has_health_issues'].map({True: 1, False: 0})

    # 年龄分段
    bins = [0, 18, 30, 45, 60, 100]
    labels = ['<18', '18-30', '30-45', '45-60', '>60']
    df['age_group'] = pd.cut(df['age'], bins=bins, labels=labels)

    # 收入分段
    income_bins = [0, 30000, 60000, 100000, 150000, 200000, 1000000]
    income_labels = ['<30K', '30-60K', '60-100K', '100-150K', '150-200K', '>200K']
    df['income_group'] = pd.cut(df['annual_income_usd'], bins=income_bins, labels=income_labels)

    # 多维度雷达图 - 不同年龄组特征对比


    age_groups = labels
    radar_data = [create_radar_chart(group) for group in age_groups]

    radar = (
        Radar(init_opts=opts.InitOpts(theme=dark_theme, width="100%", height="700px"))
        .add_schema(
            schema=[
                opts.RadarIndicatorItem(name="每日吸烟量", max_=13),
                opts.RadarIndicatorItem(name="每周饮酒量", max_=6),
                opts.RadarIndicatorItem(name="BMI指数", max_=30),
                opts.RadarIndicatorItem(name="睡眠时间", max_=8),
                opts.RadarIndicatorItem(name="戒烟尝试次数", max_=5),
                opts.RadarIndicatorItem(name="子女数量", max_=3),
            ],
            splitarea_opt=opts.SplitAreaOpts(
                is_show=True, areastyle_opts=opts.AreaStyleOpts(opacity=0.1)
            ),
            textstyle_opts=opts.TextStyleOpts(color="#fff"),
        )
    )

    colors = ['#00FFFF', '#7FFF00', '#FFD700', '#FF4500', '#FF1493']
    for i, group in enumerate(age_groups):
        radar.add(
            series_name=group,
            data=[radar_data[i]],
            linestyle_opts=opts.LineStyleOpts(width=2, color=colors[i]),
            areastyle_opts=opts.AreaStyleOpts(opacity=0.4, color=colors[i]),
            symbol="circle",
            label_opts=opts.LabelOpts(is_show=False),
        )

    radar.set_global_opts(
        title_opts=opts.TitleOpts(title="不同年龄组成瘾特征雷达图"),
        legend_opts=opts.LegendOpts(
            orient="vertical", pos_right="5%", pos_top="15%", textstyle_opts=opts.TextStyleOpts(color="#fff")
        ),
        tooltip_opts=opts.TooltipOpts(trigger="item"),
    )
    return radar

六、数据可视化看板

scss 复制代码
# 渲染所有图表
from pyecharts.charts import Page

page = Page()
page.add(
    age_distribution(),
    gender_distribution(),
    top_countries(),
    education_distribution(),
    employment_distribution(),
    income_vs_addiction(),
    age_started_boxplot(),
    quit_attempts_histogram(),
    health_vs_addiction(),
    mental_health_pie(),
    bmi_vs_smoking()
)

page.render("addiction_analysis_dark.html")

七、总结

通过上述分析和可视化,我们可以从多个维度深入了解成瘾者的特征和行为模式。这些图表不仅具有视觉冲击力,还能为公共卫生研究和教育提供有力的数据支持。希望这些代码和图表能够帮助你更好地理解和分析数据。


如果您在人工智能领域遇到技术难题,或是需要专业支持,无论是技术咨询、项目开发还是个性化解决方案,我都可以为您提供专业服务,如有需要可站内私信或添加下方VX名片(ID:xf982831907)

期待与您一起交流,共同探索AI的更多可能!

相关推荐
云天徽上15 小时前
【数据可视化】1991-2021年各国的失业数据集可视化分析
数据可视化
云天徽上2 天前
【数据可视化】2024-25 土耳其超级联赛薪资全景图:Python + PyEcharts 多维可视化实战
数据可视化
云天徽上2 天前
【数据可视化】2025 年欧足联排名数据可视化分析:Python + PyEcharts 多维可视化实战
数据可视化
云天徽上2 天前
【数据可视化】2023 年 Spotify 歌曲数据集可视化分析
数据可视化
爱分享的飘哥3 天前
第十九篇 自动化报表生成:Python一键生成可视化Excel图表与专业PDF报告,老板看了都点赞!
自动化·办公自动化·数据可视化·excel自动化·python报表·pdf报告
银之夏雪丶3 天前
AntV G6 基础元素详解(React版)
前端·javascript·数据可视化
大数据魔法师3 天前
Matplotlib(一)- 数据可视化与Matplotlib
matplotlib·数据可视化
李昊哲小课6 天前
销售数据可视化分析项目
python·信息可视化·数据分析·matplotlib·数据可视化·seaborn