一、核心功能
1. 多维度情感分析
通过SnowNLP分析好友签名情感倾向,生成五大可视化图表:
- 词云图:展示签名高频词汇分布
- 情感饼图:呈现积极/消极情绪比例
- 词频柱状图:显示TOP10关键词使用频率
- 情感趋势图:描绘签名情感分数变化曲线
- 特征散点图:揭示情感分数与签名长度的相关性
二、设计思想
1. 模块化架构
- 数据处理模块 :样本清洗(去标点、分词) 停用词过滤 情感分数计算
- 可视化模块 :词云生成器 饼图渲染器 趋势分析组件 特征关联分析
2. 增强可视化
- 采用5种图表类型多角度呈现数据
- 集成动态提示框、坐标轴格式化等交互功能
- 支持图表参数自定义(颜色、尺寸、形状)
三、核心库与函数
四、代码实现
from pyecharts.charts import WordCloud, Pie, Bar, Line, Scatter
from pyecharts import options as opts
import jieba
import re
from collections import Counter
from pyecharts.commons.utils import JsCode
from snownlp import SnowNLP
def read_text_file(file_path):
"""读取文本文件内容"""
with open(file_path, 'r', encoding='utf-8') as f:
return f.read().strip().replace('\n', '')
def analyze_emotion(signature_file, stop_file, output_html="emotion.html"):
"""
分析好友签名情感并生成多种可视化图表
:param signature_file: 签名文本文件路径
:param stop_file: 停用词文件路径
:param output_html: 输出文件名
"""
# 数据处理
text = read_text_file(signature_file)
text = re.sub(r'[^\w\s]', '', text) # 去标点
words = [w.strip() for w in jieba.lcut(text) if w.strip() and w not in get_stopwords(stop_file)]
word_counts = dict(Counter(words).most_common(200))
# 情感分析数据准备
signatures = [line.strip() for line in open(signature_file, 'r', encoding='utf-8') if line.strip()]
emotion_scores = [round(SnowNLP(s).sentiments, 2) for s in signatures] # 添加四舍五入处理
# 生成词云
wc = WordCloud()
wc.add("", list(word_counts.items()), word_size_range=[20, 100], shape='diamond')
wc.set_global_opts(title_opts=opts.TitleOpts(title="好友签名词云"))
# 生成情感饼图
pos = sum(1 for s in emotion_scores if s >= 0.5)
pie = Pie()
pie.add("", [("积极", pos), ("消极", len(emotion_scores) - pos)],
radius=["40%", "60%"], rosetype="radius")
pie.set_global_opts(title_opts=opts.TitleOpts(title="情感分布"))
# 新增柱状图(展示词频TOP10)
top_words = sorted(word_counts.items(), key=lambda x: x[1], reverse=True)[:10]
bar = Bar()
bar.add_xaxis([w[0] for w in top_words])
bar.add_yaxis("词频", [w[1] for w in top_words], color='#3398DB')
bar.set_global_opts(
title_opts=opts.TitleOpts(title="签名词频TOP10"),
xaxis_opts=opts.AxisOpts(name="关键词"),
yaxis_opts=opts.AxisOpts(name="出现次数")
)
# 新增折线图(情感分数分布)
line = Line()
x_data = list(range(1, len(emotion_scores) + 1))
line.add_xaxis(x_data)
line.add_yaxis("情感分数", emotion_scores, is_smooth=True, symbol="emptyCircle")
line.set_global_opts(
title_opts=opts.TitleOpts(title="情感分数趋势"),
tooltip_opts=opts.TooltipOpts(trigger="axis")
)
# 新增散点图(情感分数与签名长度)
signature_lengths = [len(s) for s in signatures]
scatter = Scatter()
scatter.add_xaxis(signature_lengths)
scatter.add_yaxis("情感分数",
emotion_scores,
symbol_size=10,
label_opts=opts.LabelOpts( # 添加标签格式化
formatter=JsCode(
"function(params) {return params.value[1];}" # 直接显示两位小数
)
))
scatter.set_global_opts(
title_opts=opts.TitleOpts(title="情感分数 vs 签名长度"),
xaxis_opts=opts.AxisOpts(name="签名长度"),
yaxis_opts=opts.AxisOpts(
name="情感分数",
axislabel_opts=opts.LabelOpts(formatter="{value} 分") # 添加单位说明
),
tooltip_opts=opts.TooltipOpts( # 优化提示框显示
formatter=JsCode(
"function(params) {return '长度: ' + params.value[0] + '<br/>分数: ' + params.value[1];}"
)
)
)
# 渲染所有图表
wc.render("词云.html")
pie.render("情感饼图.html")
bar.render("词频柱状图.html")
line.render("情感趋势折线图.html")
scatter.render("情感散点图.html")
def get_stopwords(file_path):
"""获取停用词列表"""
with open(file_path, 'r', encoding='utf-8') as f:
return set([line.strip() for line in f])
analyze_emotion("好友个性签名.txt", "停用词.txt")
五、输出结果
-
可视化报告集:
词云.html
:交互式签名词云情感饼图.html
:情绪比例分布词频柱状图.html
:TOP10关键词排行情感趋势折线图.html
:情感波动分析情感散点图.html
:长度-分数关联分析
-
技术特征:
- 所有图表支持鼠标悬停查看数值细节
- 自适应移动端/PC端显示
- 图表元素支持导出PNG/SVG格式