使用Python进行数据分析可视化

张开发
2026/4/4 11:07:00 15 分钟阅读
使用Python进行数据分析可视化
使用Python完成简单的数据试图化有以下几个功能库帮助我们快速完成。1. pandas- 用途读取人员基本信息表Excel/CSV、数据清洗、筛选、统计​- 功能读取文件、分组统计、处理缺失值、生成各类统计数据性别、省份、城市、成绩、生日等2. matplotlib- 用途基础绘图、折线图、柱状图、散点图、饼图​- 功能画所有基础图表可自定义颜色、标题、标签、布局3. seaborn- 用途美化图表、折线图、散点图、分布图​- 功能比 matplotlib 更好看画成绩分布、生日散点图特别合适二、地图可视化省份中国地图4. pyecharts- 用途中国地图可视化省份分布​- 功能直接生成交互式中国地图支持省份热力图、颜色深浅表示人数5. echarts-countries-pypkg / echarts-china-provinces-pypkg- 用途提供中国省份地图数据​- 功能给 pyecharts 提供地图底图否则无法画中国地图三、词云签名词云6. wordcloud- 用途生成签名词云图​- 功能把文本签名转成词云支持自定义形状、颜色、字体7. jieba- 用途中文分词签名必须分词才能做词云​- 功能把中文签名拆成词语否则词云无法生成四、关系图8. networkx- 用途画关系图、网络图、节点连线图​9. pyvis可选更美观- 用途交互式关系网络图​- 功能生成可拖拽、可放大的网页版接下来以大学学生信息数据分析为例展示以下各个库的实际效果- 读取学生表 → pandas​- 性别饼图 → matplotlib / seaborn1. 先安装依赖如果没装pip install pandas openpyxl2. 读取 xlsx 文件代码import pandas as pd# 读取 Excel 文件把路径换成你的文件路径df pd.read_excel(学生性别统计.xlsx, sheet_name0) # sheet_name0 表示读取第一个工作表# 查看数据确认读取成功print(读取到的数据)print(df)3. 假设 Excel 格式如下班级 男生 女生软件233 22 10软件232 26 12软件231 12 34. 读取后直接提取数据画饼图用# 提取班级、男生、女生数据classes df[班级].tolist()boys df[男生].tolist()girls df[女生].tolist()print(班级, classes)print(男生, boys)print(女生, girls)- 省份中国地图 → pyecharts 地图包12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273import pandas as pdfrom pyecharts import options as optsfrom pyecharts.charts import Mapfrom pyecharts.globals import ThemeType# ---------------------- 1. 读取你提供的学生信息表 ----------------------# 直接读取你的Excel文件列名完全匹配file_path 软件232学生信息表.xlsxdf pd.read_excel(file_path)# 统计各省份生源人数列名生源省份完全匹配你的表格province_count df[生源省份].value_counts().reset_index()province_count.columns [省份, 人数]# 统一省份名称格式解决山西和山西省等不一致问题保证地图正常显示province_map {山西: 山西省,山东: 山东省,重庆: 重庆市}province_count[省份] province_count[省份].replace(province_map)# 转换为pyecharts要求的格式[[省份1, 人数1], [省份2, 人数2], ...]data_pair list(zip(province_count[省份], province_count[人数]))# ---------------------- 2. 绘制全国生源省份地图 ----------------------map_chart (Map(init_optsopts.InitOpts(themeThemeType.LIGHT, width1400px, height800px)).add(series_name软件232班生源人数,data_pairdata_pair,maptypechina,is_map_symbol_showFalse,label_optsopts.LabelOpts(is_showTrue, font_size10, color#fff),).set_global_opts(title_optsopts.TitleOpts(title齐齐哈尔大学软件232班2023级生源省份分布地图,subtitle数据来源软件232学生信息表,pos_leftcenter,title_textstyle_optsopts.TextStyleOpts(font_size22)),visualmap_optsopts.VisualMapOpts(min_0,max_province_count[人数].max(),is_piecewiseTrue,pieces[{min: 6, label: 6人以上, color: #c23531},{min: 3, max: 5, label: 3-5人, color: #d48265},{min: 2, max: 2, label: 2人, color: #91c7ae},{min: 1, max: 1, label: 1人, color: #6e7074},{value: 0, label: 0人, color: #f0f0f0}],pos_left20px,pos_bottom20px),tooltip_optsopts.TooltipOpts(triggeritem,formatter{b}: {c} 人)).render(软件232班生源省份地图.html))print(✅ 地图已生成软件232班生源省份地图.html)print(\n 各省份生源人数统计)print(province_count.to_string(indexFalse))# ---------------------- 3. 提取生源城市列表满足作业第一个要求 ----------------------city_list df[生源城市].dropna().unique().tolist()print(\n️ 生源城市列表)for city in city_list:print(f- {city})- 城市柱状图 → matplotlibimport pandas as pdimport matplotlib.pyplot as pltimport numpy as npfrom collections import Counter# 基础设置 # 解决Matplotlib中文显示问题plt.rcParams[font.sans-serif] [SimHei, WenQuanYi Zen Hei, Microsoft YaHei]plt.rcParams[axes.unicode_minus] False# 设置图表样式plt.rcParams[figure.facecolor] whiteplt.rcParams[axes.facecolor] white# 数据整理 # 整合231/232/233班有效生源数据过滤空值data_231 [{班级: 软件231, 省份: 江苏省, 城市: 徐州市},{班级: 软件231, 省份: 浙江省, 城市: 宁波市},{班级: 软件231, 省份: 浙江省, 城市: 金华市},{班级: 软件231, 省份: 河北省, 城市: 保定市},{班级: 软件231, 省份: 江西省, 城市: 萍乡市},{班级: 软件231, 省份: 山西省, 城市: 太原市},{班级: 软件231, 省份: 黑龙江省, 城市: 齐齐哈尔市},{班级: 软件231, 省份: 黑龙江省, 城市: 绥化市},{班级: 软件231, 省份: 黑龙江省, 城市: 绥化市}]data_232 [{班级: 软件232, 省份: 山西省, 城市: 阳泉市},{班级: 软件232, 省份: 江苏省, 城市: 泰州市},{班级: 软件232, 省份: 河南省, 城市: 信阳市},{班级: 软件232, 省份: 山东省, 城市: 济南市},{班级: 软件232, 省份: 海南省, 城市: 澄迈县},{班级: 软件232, 省份: 河北省, 城市: 沧州市},{班级: 软件232, 省份: 重庆市, 城市: 重庆市},{班级: 软件232, 省份: 宁夏, 城市: 固原市},{班级: 软件232, 省份: 内蒙古, 城市: 赤峰市},{班级: 软件232, 省份: 黑龙江省, 城市: 哈尔滨市},{班级: 软件232, 省份: 黑龙江省, 城市: 齐齐哈尔市},{班级: 软件232, 省份: 黑龙江省, 城市: 鸡西市},{班级: 软件232, 省份: 黑龙江省, 城市: 七台河市},{班级: 软件232, 省份: 黑龙江省, 城市: 绥化市},{班级: 软件232, 省份: 黑龙江省, 城市: 黑河市},{班级: 软件232, 省份: 贵州省, 城市: 黔东南州},{班级: 软件232, 省份: 江西省, 城市: 赣州市},{班级: 软件232, 省份: 甘肃省, 城市: 平凉市},{班级: 软件232, 省份: 福建省, 城市: 泉州市},{班级: 软件232, 省份: 四川省, 城市: 成都市},{班级: 软件232, 省份: 河南省, 城市: 新乡市/焦作市/平顶山市等7人}]data_233 [{班级: 软件233, 省份: 四川省, 城市: 遂宁市},{班级: 软件233, 省份: 天津市, 城市: 天津市},{班级: 软件233, 省份: 山东省, 城市: 济宁市},{班级: 软件233, 省份: 上海市, 城市: 上海市},{班级: 软件233, 省份: 湖北省, 城市: 荆州市},{班级: 软件233, 省份: 河北省, 城市: 唐山市},{班级: 软件233, 省份: 贵州省, 城市: 赤水市},{班级: 软件233, 省份: 甘肃省, 城市: 天水市},{班级: 软件233, 省份: 吉林省, 城市: 通化市},{班级: 软件233, 省份: 云南省, 城市: 楚雄州},{班级: 软件233, 省份: 黑龙江省, 城市: 哈尔滨市5人},{班级: 软件233, 省份: 黑龙江省, 城市: 齐齐哈尔市/大庆市等5人}]# 合并数据并转为DataFrameall_data data_231 data_232 data_233df pd.DataFrame(all_data)# 统计各班级省份/城市人数cls_list [软件231, 软件232, 软件233]province_count {cls: Counter(df[df[班级]cls][省份]) for cls in cls_list}city_count {cls: Counter(df[df[班级]cls][城市]) for cls in cls_list}# 提取所有唯一省份/城市用于x轴统一all_provinces list(set(df[省份]))all_cities list(set([city for cls in cls_list for city in city_count[cls].keys()]))# 绘制图表 # 创建2行1列子图设置画布大小fig, (ax1, ax2) plt.subplots(2, 1, figsize(18, 14))fig.suptitle(软件231-233班学生生源省份城市分布对比, fontsize22, fontweightbold, y0.98)# 配色方案区分三个班级colors [#1f77b4, #ff7f0e, #2ca02c]bar_width 0.25 # 柱状图宽度x_prov np.arange(len(all_provinces)) # 省份x轴坐标x_city np.arange(len(all_cities)) # 城市x轴坐标# --- 子图1省份分布对比柱状图 ---for i, cls in enumerate(cls_list):vals [province_count[cls].get(p, 0) for p in all_provinces]ax1.bar(x_prov i*bar_width, vals, bar_width, labelcls,colorcolors[i], alpha0.8, edgecolorwhite, linewidth1.5)# 省份图样式设置ax1.set_xlabel(生源省份, fontsize14, fontweightbold)ax1.set_ylabel(学生人数, fontsize14, fontweightbold)ax1.set_title(各班级生源省份分布对比, fontsize18, fontweightbold, pad20)ax1.set_xticks(x_prov bar_width)ax1.set_xticklabels(all_provinces, rotation45, haright, fontsize12)ax1.legend(fontsize12, locupper right)ax1.grid(axisy, alpha0.3, linestyle--)# 添加数值标签for i, cls in enumerate(cls_list):vals [province_count[cls].get(p, 0) for p in all_provinces]for j, v in enumerate(vals):if v 0:ax1.text(x_prov[j]i*bar_width, v0.05, str(v), hacenter, vabottom, fontsize10, fontweightbold)# --- 子图2城市分布对比柱状图 ---for i, cls in enumerate(cls_list):vals [city_count[cls].get(c, 0) for c in all_cities]ax2.bar(x_city i*bar_width, vals, bar_width, labelcls,colorcolors[i], alpha0.8, edgecolorwhite, linewidth1.5)# 城市图样式设置ax2.set_xlabel(生源城市, fontsize14, fontweightbold)ax2.set_ylabel(学生人数, fontsize14, fontweightbold)ax2.set_title(各班级生源城市分布对比, fontsize18, fontweightbold, pad20)ax2.set_xticks(x_city bar_width)ax2.set_xticklabels(all_cities, rotation45, haright, fontsize12)ax2.legend(fontsize12, locupper right)ax2.grid(axisy, alpha0.3, linestyle--)# 添加数值标签for i, cls in enumerate(cls_list):vals [city_count[cls].get(c, 0) for c in all_cities]for j, v in enumerate(vals):if v 0:ax2.text(x_city[j] i * bar_width, v 0.05, str(v), hacenter, vabottom, fontsize10,fontweightbold)# 保存与展示 plt.tight_layout() # 自动调整布局plt.subplots_adjust(top0.95) # 调整顶部边距适配总标题# 保存图片可修改路径plt.savefig(软件231-233生源省份城市对比图.png, dpi300, bbox_inchestight)# 展示图表PyCharm中会弹出窗口plt.show()# 输出统计汇总print( * 50)print(软件231-233班生源统计汇总)print( * 50)for cls in cls_list:cls_data df[df[班级] cls]top_prov province_count[cls].most_common(1)[0]print(f{cls}总人数{len(cls_data)} | 涉及省份{len(set(cls_data[省份]))}个 | 核心生源{top_prov[0]}{top_prov[1]}人)- 签名词云 → wordcloud jiebaimport matplotlib.pyplot as pltimport numpy as npimport jiebafrom wordcloud import WordCloudfrom matplotlib.font_manager import FontPropertiesfrom PIL import Imageimport sys# 设置中文字体font FontProperties(fnamerC:\Windows\Fonts\simfang.ttf)def get_top_words_from_text(filename):从原始文本文件中分词并统计词频with open(filename, r, encodingutf-8) as f:text f.read()# 使用 jieba 分词words jieba.lcut(text)# 过滤掉停用词和单字可选stop_words {的, 了, 在, 是, 我, 有, 和, 就, 不, 人, 都, 一, 一个, 上, 也, 很,到, 说, 要, 去, 你, 会, 着, 没有, 看, 好, 自己, 这}words [word for word in words if len(word) 1 and word not in stop_words]# 统计词频from collections import Counterword_counts Counter(words)return word_countsdef generate_word_cloud(output_image, word_freq_dict, font_path, mask_imageNone):生成词云图if mask_image:mask np.array(Image.open(mask_image))wc WordCloud(font_pathfont_path, background_colorwhite, maskmask, max_words200)else:wc WordCloud(font_pathfont_path, background_colorwhite, max_words200)wc.generate_from_frequencies(word_freq_dict)#plt.imshow(wc, interpolationbilinear)#plt.axis(off)#plt.show()wc.to_file(output_image)def main():# 从原始文本文件直接处理top_words_with_freq get_top_words_from_text(政府工作报告2021.txt)# 生成词云generate_word_cloud(b.jpg, top_words_with_freq, rC:\Windows\Fonts\simfang.ttf, santi_cloud.png)if __name__ __main__:main()- 生日散点图 → matplotlib / seabornimport matplotlib.pyplot as plt# 生日数据从图片中提取birthdays [2005.01.07, 2004.08.25, 2004.12.30, 2004.12.09, 2005.07.04,2005.6.11, 2004.11.21, 2004.12.28, 2005.3.18, 2005.12.10,2005.07.21, 2005.04.03, 2004.11.18, 2004.06.30, 2004.08.25,2005.03.10, 2005.07.24, 2005.02.15, 2004.12.29]# 解析月份和日期months []days []for bd in birthdays:parts bd.split(.)month int(parts[1]) # 第二部分是月份day int(parts[2]) # 第三部分是日期months.append(month)days.append(day)# 绘图plt.figure(figsize(10, 6))# 使用五角星标记与原参考代码一致点大小与日期相关乘以50使大小适中plt.scatter(months, days, s[d*50 for d in days], cyellow,marker(5, 1), alpha0.6, linewidths2, edgecolorsnone)# 设置坐标轴范围plt.xlim(0.5, 12.5) # 月份左右留出间隙plt.ylim(0, 32) # 日期从0到321~31可见plt.xticks(range(1, 13)) # 设置月份刻度plt.yticks(range(1, 32, 5)) # 日期刻度间隔5天# 添加标签和标题plt.xlabel(Month)plt.ylabel(Day)plt.title(Birthday Distribution (Month vs Day))# 显示网格可选plt.grid(alpha0.3)plt.show()

更多文章