🧑 博主简介:曾任某智慧城市类企业算法总监,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
五、数据可视化完整代码(可直接运行)
加载需要的处理库和简单的数据清洗:
import pandas as pdimport numpy as npfrom pyecharts.charts import *from pyecharts.globals import ThemeType, SymbolTypeimport warnings, math, randomfrom pyecharts.commons.utils import JsCodefrom pyecharts import options as optswarnings.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 年龄分布直方图(平滑密度图)
# 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 性别分布玫瑰图
# 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 国家分布
# 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 教育水平分布饼图
# 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 就业状况分布饼图
# 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 吸烟/饮酒散点图(按性别着色)
# 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 开始吸烟和饮酒年龄的箱线图
# 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 尝试戒烟/戒酒次数直方图
# 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 吸烟/饮酒量(分组箱线图)
# 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 心理健康状态分布饼图
# 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 与吸烟量散点图
# 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 吸烟与饮酒的双玫瑰图
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 多维度雷达图
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
六、数据可视化看板
# 渲染所有图表from pyecharts.charts import Pagepage = 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的更多可能!