【数据可视化】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的更多可能!

相关推荐
杨超越luckly4 小时前
基于 Overpass API 的城市电网基础设施与 POI 提取与可视化
python·数据可视化·openstreetmap·电力数据·overpass api
用户59625857360613 小时前
【征文计划】当AI Glasses成为你的“植物百科全书”
数据可视化
HsuHeinrich3 天前
利用面积图探索历史温度的变化趋势
python·数据可视化
CodeCraft Studio6 天前
空间天气监测,TeeChart助力实现太阳活动数据的可视化分析
信息可视化·数据挖掘·数据分析·数据可视化·teechart·科研图表·图表库
FIT2CLOUD飞致云6 天前
安全漏洞修复,API数据源支持添加时间戳参数,DataEase开源BI工具v2.10.17 LTS版本发布
开源·数据可视化·dataease·bi·数据大屏
图扑可视化7 天前
图扑 HT 智慧汽车展示平台全自研技术方案
汽车·数据可视化·组态监控·汽车展示
Highcharts.js8 天前
Highcharts开发解析:从数据可视化到用户体验的全面指南
信息可视化·前端框架·数据可视化·ux·highcharts·交互图表
数字冰雹9 天前
为城市治理装上“数字引擎”
中间件·数据可视化
Highcharts.js9 天前
学习 Highcharts 可视化开发的有效途径
学习·数据可视化·highcharts·图表开发·可视化开发
易知微EasyV数据可视化10 天前
数字孪生文旅:以某地智慧乡村数字孪生驾驶舱建设为例
经验分享·数字孪生·数据可视化·智慧文旅