ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

用Python+pyecharts打造电影票房与评分可视化看板

用Python+pyecharts打造电影票房与评分可视化看板 简介一份基于Python与pyecharts的国内上映电影票房评分可视化分析项目源码面向Python初学者、课程设计与期末大作业人群可快速实现从数据采集、清洗到多维度可视化展示的完整流程。项目覆盖豆瓣、猫眼、时光网等数据源围绕电影票房、评分、类型、上映月份、演员等维度生成动态图表并配有详细代码注释与文档说明。压缩包共33个文件整体约2.74MB包含6个py源码、1个ipynb交互式笔记本、10个html可视化页面、9个png结果截图、3个csv数据文件以及README、gitignore等辅助文件结构清晰便于按步骤复现。已有138人学习下载特别适合作为期末大作业或课程设计高分模板也适合新手模仿练习理解Python数据分析与pyecharts可视化的实际应用。1. 为什么“票房评分”值得做成一版可视化这个项目解决的是判断力问题电影票房排行榜每天都在变评分数据散落在各个平台单独看数值很难看出门道。把国内上映电影的票房和评分数据拉到一起按类型、档期、产地切开来观察能回答一个很实际的问题高票房到底是不是靠口碑撑起来的还是档期和宣发在起作用。用 Python 做数据清洗再交给 pyecharts 生成交互图表这套组合是目前最轻量的落地路径——不需要前端基础不需要搭服务一个脚本跑完就能在浏览器里拖拽、缩放、看提示框。适合正在学 Python 数据分析的人也适合需要快速出图表做汇报的产品和运营。源码结构也不复杂数据采集、清洗、可视化三层分开文档说明里把每个函数的作用和参数都标注到位照着跑一遍再改成自己的数据源就能迁移到其他分析场景。2. 从散乱数据到可用 DataFrame字段设计、清洗规则与聚合口径做票房评分可视化最容易翻车的地方不是画图而是数据进 DataFrame 之前的那几步。公开渠道拿到的数据通常长这样电影名带着上映年份后缀票房数字有的以“万”结尾、有的以“亿”结尾评分有的精确到小数点后一位、有的直接缺失。不把这些字段整理成统一口径后面画图时会出现坐标轴乱跳、tooltip 显示错位、排序结果对不上的问题。先把字段设计定下来再去写清洗函数是少走弯路的关键。2.1 字段设计一张表装下票房、评分和分类维度我一般会设计一张宽表字段包括电影名称、上映日期、类型、制片地区、总票房单位统一为万元、想看人数、豆瓣评分、评分人数、导演和主演。不要直接把“票房”存成字符串也不要把“评分”和“评分人数”混在一个字段里。类型字段可以考虑用逗号分隔的字符串存储因为一部电影通常属于多个类型比如“剧情,喜剧,爱情”画图时再拆分这样既保留了原始信息又给后续分析留了余地。票房单位需要统一。常见的做法是写一个转换函数读取原始字符串判断单位是“亿”还是“万”再统一换算成“万元”存储为浮点数。这样排序、求和、计算占比时才不会出错。日期字段建议直接转成 datetime 类型方便后续按月份、档期聚合。评分和评分人数是两类不同的指标评分反映口碑评分人数反映热度后面做散点图时这两个字段分别是 Y 轴和气泡大小缺一不可。2.2 清洗规则去重、缺失值填充与异常值拦截数据清洗的优先级是先去重再处理缺失最后拦截异常值。去重不能只按电影名去重因为不同年份可能上映同名电影常见做法是多列联合去重电影名加上映日期日期精确到月即可。缺失值处理要分字段区别对待票房缺失直接删掉整行评分缺失可以填充为该类型电影的平均分并在后面画图时用半透明颜色标注这些填充点提醒看图的人这部分数据是估算的。异常值拦截是很多新手容易忽略的环节。比如某部电影标注总票房 1.2 亿但评分人数只有 98 人这明显不合理通常是原始数据录入错误。拦截方法是用 pandas 的 describe() 查看字段分布找出评分人数极端低但票房却很高的记录再结合导演、主演字段人工判断。还有一个常见问题是把“累计票房”和“首日票房”混在一起标题里写的是“总票房”清洗时就只保留累计值不要混入分日数据。清洗后的数据建议另存为一个 CSV 文件后续画图都从这个文件读取避免重复执行清洗逻辑。import pandas as pd def load_and_clean(raw_path: str, output_path: str) - pd.DataFrame: df pd.read_csv(raw_path, encodingutf-8-sig) # 去重同一部电影同月上映只保留一条 df df.drop_duplicates(subset[电影名称, 上映月份], keepfirst) # 票房单位转换统一转为万元 def to_wan(value: str) - float: value str(value).strip() if value.endswith(亿): return float(value[:-1]) * 10000 if value.endswith(万): return float(value[:-1]) return float(value) df[总票房(万元)] df[总票房].apply(to_wan) # 缺失评分按类型均值填充并打标记 df[评分缺失标记] df[豆瓣评分].isna().astype(int) df[豆瓣评分] df.groupby(类型)[豆瓣评分].transform(lambda s: s.fillna(s.mean())) # 异常值拦截票房很高但评分人数极低的记录降权标注 df[异常标记] ((df[总票房(万元)] 50000) (df[评分人数] 500)).astype(int) df.to_csv(output_path, indexFalse, encodingutf-8-sig) return df cleaned load_and_clean(raw_movies.csv, cleaned_movies.csv)这段代码的核心是三个动作联合去重、单位转换和缺失值处理。联合去重用到了 subset 参数这里的“上映月份”是提前从完整日期里提取好的列保留规则取第一条实际业务中如果想保留最新数据可以把 keep 改为 last 并按日期排序后再去重。单位转换函数用了字符串结尾判断注意 float(value[:-1]) 这里假定原始数据不会出现“1.23亿”和“1.23亿人次”混写的情况如果混写需要再加一层判断。缺失评分按类型均值填充比全局均值更合理因为不同类型电影的评分基线差异较大。异常标记列不会参与后续计算但画散点图时可以将它映射为颜色让看图的人一眼识别出可疑数据。2.3 聚合口径档期、类型、产地三种切片方式清洗只是第一步真正让图表有意义的是聚合口径。标题里写的是“国内上映”那就有三种主流切法按档期切春节档、暑期档、国庆档、按类型切剧情、动作、喜剧、按产地切国产片、进口片、合拍片。三种切法对应三张不同的图表档期适合看柱状图趋势类型适合看饼图占比产地适合看分组柱状图。聚合时要注意票房字段用 sum评分字段用加权平均权重是评分人数而不是简单平均否则一部评分人数只有几百人的小众电影会把整体评分拉偏。def aggregate_by_period(df: pd.DataFrame) - pd.DataFrame: def assign_period(month: int) - str: if month in (1, 2): return 春节档 if month in (7, 8): return 暑期档 if month 10: return 国庆档 return 普通档 df[档期] df[上映月份].apply(assign_period) grouped df.groupby(档期).agg( 总票房(总票房(万元), sum), 加权评分(豆瓣评分, lambda s: round((s * df.loc[s.index, 评分人数]).sum() / max(df.loc[s.index, 评分人数].sum(), 1), 2)) ).reset_index() return grouped.sort_values(总票房, ascendingFalse) period_data aggregate_by_period(cleaned) print(period_data)这里有个细节值得注意计算加权评分时我用了 df.loc[s.index] 而不是直接使用 s因为 groupby 的 agg 里匿名函数的参数 s 是 Series但它的索引是原始 DataFrame 的索引切片必须通过这个索引去原表里取对应的评分人数。如果直接写 s * df[评分人数]会因为索引错位而得到全是 NaN 的结果。聚合完成后按总票房降序排序这样画柱状图时不需要额外处理pyecharts 会按照传入数据的顺序绘制数据排好序图表的视觉效果会好很多。3. 用 pyecharts 构建票房与评分的四张核心视图参数与配置深度拆解pyecharts 的 API 设计分成两部分负责生成图表的类Bar、Scatter、Map 等和负责配置的组件TitleOpts、TooltipOpts、VisualMapOpts 等。类决定图表类型组件决定图表的交互行为和视觉表现。这一章不讲全部配置项只挑票房评分可视化里最常用、最能出效果的四张图票房 TOP 榜柱状图、评分分布直方图、票房-评分散点图和票房占比饼图。每张图都有明确的受众和阅读目标配置参数也会同步解释。3.1 票房 TOP 榜柱状图反转坐标轴与标签显示策略票房 TOP 榜适合用横向柱状图因为电影片名普遍较长横向排列可以完整显示电影名称避免斜体或截断。数据量控制在 15 部以内超过 15 部后柱状图会变得拥挤标签也会相互遮挡。反转坐标轴用 yaxis_inverseTrue这个参数名在 pyecharts 里不算直白第一次用很容易漏掉。标签显示策略上数值标签精确保留到整数即可不需要小数点后两位单位在副标题里说明避免每个标签都带“万”字造成视觉噪音。from pyecharts.charts import Bar from pyecharts import options as opts from pyecharts.globals import ThemeType def make_top_bar(df: pd.DataFrame, top_n: int 15) - Bar: top_data df.sort_values(总票房(万元), ascendingFalse).head(top_n) bar ( Bar(init_optsopts.InitOpts(themeThemeType.LIGHT, width1000px, height600px)) .add_xaxis(top_data[电影名称].tolist()) .add_yaxis( 总票房(万元), top_data[总票房(万元)].tolist(), bar_width18, label_optsopts.LabelOpts(positionright, formatter{c} 万), ) .reversal_axis() .set_global_opts( title_optsopts.TitleOpts(title国内上映电影票房 TOP 榜, subtitle单位万元), xaxis_optsopts.AxisOpts(name票房(万元), axislabel_optsopts.LabelOpts(formatter{value} 万)), yaxis_optsopts.AxisOpts(name电影名称, axislabel_optsopts.LabelOpts(font_size12)), tooltip_optsopts.TooltipOpts(triggeraxis, axis_pointer_typeshadow), ) ) return bar top_chart make_top_bar(cleaned) top_chart.render(票房top榜.html)反转坐标轴的逻辑要从数据传递顺序去理解先 add_yaxis 传入的列表顺序是从大到小此时 X 轴是电影名Y 轴是数值调用 reversal_axis() 后X 轴和 Y 轴的角色互换原来传入的第一个值显示在最上方。所以 head(top_n) 取到的最头部数据会出现在图表最顶端符合阅读习惯。LabelOpts 的 formatter 参数使用字符串模板{c} 表示当前数据点的值后面拼接“万”字即可如果不想让标签和柱子重叠position 可以改为 right这也是最通用的横向柱状图标签位置。bar_width 控制柱子宽度18 像素在 15 条数据、600 像素高的画布上效果合适数据量大时可以适当调小。3.2 评分分布直方图用 pyecharts 的 Bar 数据分箱模拟直方图pyecharts 原生没有 histogram 类型但评分分布是连续变量思路是用 cut 函数把 0 到 10 的评分切成若干个区间然后统计每个区间内的电影数量。区间划分要均匀常见做法是 0-2、2-4、4-6、6-8、8-10 五个区间但如果数据量足够多可以细化到 1 分一档。分箱的结果用 Bar 展示X 轴是区间标签Y 轴是电影数量。这张图能直观看出评分是否集中在某个区间比如大量电影集中在中高分段说明平台用户打分偏向宽容或者上映的电影整体质量确实不错。import numpy as np def make_score_histogram(df: pd.DataFrame, bin_size: float 1.0) - Bar: bins np.arange(0, 10.1, bin_size) labels [f{int(bins[i])}-{int(bins[i1])} for i in range(len(bins)-1)] df[评分区间] pd.cut(df[豆瓣评分], binsbins, labelslabels, rightFalse) count_series df[评分区间].value_counts().sort_index() bar ( Bar() .add_xaxis(count_series.index.tolist()) .add_yaxis(电影数量, count_series.values.tolist(), category_gap40%) .set_global_opts( title_optsopts.TitleOpts(title评分分布直方图), xaxis_optsopts.AxisOpts(name评分区间), yaxis_optsopts.AxisOpts(name电影数量), tooltip_optsopts.TooltipOpts(triggeraxis), ) ) return barpd.cut 的 rightFalse 意思是区间左闭右开即 [0, 1)、[1, 2) 这样的划分避免边界值同时落入两个区间。category_gap40%是柱状图的组间距参数设为百分比形式表示柱子之间的间距占柱宽的比例。pyecharts 的柱状图默认 category_gap 是 20%对于直方图应用40% 左右的间距能减少柱子的拥挤感。value_counts() 的结果默认按数量降序排列这里必须加 sort_index() 把它恢复成按评分区间升序排列否则图表上的横轴顺序是乱的。如果 bin_size 改为 0.5labels 列表的生成要相应调整不能再用 int() 取整否则标签会重复。3.3 票房-评分散点图气泡大小映射评分人数与异常值过滤散点图是四张图里信息密度最高的一张。X 轴是票房Y 轴是评分每个点代表一部电影点的大小映射评分人数。这样做有双重价值高票房低评分的电影和低票房高评分的电影都能一眼挑出来前者可能是烂片但宣发强势后者可能是遗珠。气泡大小用 SymbolSize 控制pyecharts 的 Scatter 图需要自己算好尺寸常见的算法是取评分人数的对数再映射到 5 到 40 的区间直接线性映射会让极端值把其他点全部压缩成小点。from pyecharts.charts import Scatter def make_score_scatter(df: pd.DataFrame) - Scatter: plot_df df[df[异常标记] 0].copy() # 气泡尺寸评分人数取对数后线性映射到 5-40 log_cnt np.log10(plot_df[评分人数] 1) size 5 (log_cnt - log_cnt.min()) / (log_cnt.max() - log_cnt.min()) * 35 scatter ( Scatter() .add_xaxis(plot_df[总票房(万元)].tolist()) .add_yaxis( 电影, plot_df[[豆瓣评分, 总票房(万元)]].values.T.tolist(), symbol_sizesize.tolist(), label_optsopts.LabelOpts(is_showFalse), ) .set_global_opts( title_optsopts.TitleOpts(title票房-评分分布散点图), xaxis_optsopts.AxisOpts(name总票房(万元), type_value), yaxis_optsopts.AxisOpts(name豆瓣评分, type_value, min_0, max_10), tooltip_optsopts.TooltipOpts(formatter{b}: 票房 {c0} 万, 评分 {c1}), visualmap_optsopts.VisualMapOpts(dimension1, max_10, pos_left10%), ) ) return scatterScatter 在传入 Y 轴数据时接受二维列表每个内部列表的格式是 [数值1, 数值2]这里数值1 是评分数值2 是票房。add_yaxis 的第一个参数是系列名称散点图里它只显示在图例中我这里写的是“电影”。tooltip 的 formatter 用了 {c0} 和 {c1}分别对应二维列表中的两个值{b} 是数据项名称这里没有给每部电影设置名称因此 {b} 会显示为序号。如果想要鼠标悬停时显示电影名称需要改用 add_xaxis 传入完整数据对而不是分开传或者将电影名称作为每个点的 name 属性传入。visualmap_opts 配置了右侧的视觉映射组件拖拽它能筛选高评分区间dimension1 表示作用于 Y 轴数据。3.4 票房占比饼图只有三种类型该出现的场景饼图是最容易被滥用的图表类型但票房占比排序 TOP 5 类型时确实合适。使用场景有限制数据必须是一组总和为 100% 的组成部分且分类不超过 7 个。超过 7 个时小占比类型会挤成一团标签完全无法阅读。解法是先把占比小于 3% 的类型归为“其他”类然后画图和颜色配置交给 pyecharts。饼图在这个项目里是辅助视图真正的分析重点在散点图。4. 把单图拼成仪表盘用 Grid、Tab 和 Overlap 组合出可交互分析工作台单张图的价值有限把多张图放到同一个 HTML 页面里配合 Tab 切换才能形成“票房看趋势、评分看分布、交叉看关系”的分析节奏。pyecharts 提供了 Page、Tab、Grid 三种组合方式Page 是纵向堆叠Tab 是标签页切换Grid 是把多图放到同一个坐标系里。票房评分可视化项目里最常见的搭配是开头用 Tab 分三页票房榜单页、评分分布页、关联分析页。每页内部再用 Page 或 Grid 放置两张图。4.1 Tab 切换让报告式分析更友好Tab 的使用非常简单把配置好的图表实例 add 进去最后生成一个 HTML。但有个细节需要注意Tab 内部的图表建议设置统一的宽高否则切换页面时容器尺寸跳动影响体验。推荐在 init_opts 里显式指定宽高比如 1000x600。这个值要和所有子图保持一致。from pyecharts.charts import Tab tab Tab() tab.add(top_chart, 票房榜) tab.add(score_hist, 评分分布) tab.add(scatter_chart, 关联分析) tab.render(电影票房评分看板.html)Tab 生成的页面底部会出现标签栏用户点击即可切换。如果你的数据量很大比如散点图里有上千个点建议在生成最终报告时只保留散点图一页因为浏览器在处理大量 SVG 图形时会有明显卡顿。pyecharts 默认渲染 SVG 格式可以改为 Canvas 模式在 InitOpts 里设置 renderercanvas这会显著提升散点图在数据量大时的交互流畅度。我在做这类看板时统一设置 renderercanvas只在需要矢量缩放打印的场景下切回 SVG。4.2 Grid 组合共享坐标系叠加面积图与折线图Grid 是 pyecharts 提供的底层组合能力它允许在一张图表容器内放置多个坐标系实现类似“柱状图 折线图双轴”的效果。例如左侧 X 轴是档期左侧 Y 轴是总票房用柱状图右侧 Y 轴是平均评分用折线图这样的组合可以在一个视图中对比“量”和“质”的关系。from pyecharts.charts import Bar, Line, Grid def make_period_combined(period_df: pd.DataFrame) - Grid: bar ( Bar() .add_xaxis(period_df[档期].tolist()) .add_yaxis( 总票房(万元), period_df[总票房].tolist(), yaxis_index0, label_optsopts.LabelOpts(positiontop), ) .set_global_opts(yaxis_optsopts.AxisOpts(name票房, positionleft)) ) line ( Line() .add_xaxis(period_df[档期].tolist()) .add_yaxis( 加权评分, period_df[加权评分].tolist(), yaxis_index1, label_optsopts.LabelOpts(positiontop, formatter{c} 分), ) .set_global_opts(yaxis_optsopts.AxisOpts(name评分, positionright, min_0, max_10)) ) grid ( Grid() .add(bar, grid_optsopts.GridOpts(pos_left15%, pos_right15%)) .add(line, grid_optsopts.GridOpts(pos_left15%, pos_right15%)) ) return grid关键点在 add 方法的顺序和坐标系索引。bar 和 line 都通过 yaxis_index 指定了不同的 Y 轴但 X 轴是共享的。GridOpts 的 pos_left 和 pos_right 为左右两侧的 Y 轴留出空间否则轴标签会超出画布边界。这里的 Grid 是合并图表的关键两个图共用一份坐标系而不是互相覆盖。如果你的项目里还需要把柱状图和饼图同时叠在一起显示Grid 就不适用了——饼图是极坐标系柱状图是直角坐标系两者坐标系性质不同只能做 Tab 或 Page 切换。4.3 Page 布局纵向流式排布适合报告打印Page 是三种组合中最简单的图表按顺序垂直排布。它的好处是滚动查看不打断阅读逻辑。Page 还支持懒加载功能数据量大时可以通过 Page(layoutPage.SimplePageLayout) 来按需渲染。做电影票房变现看板时如果不想让用户切换 Tab而是希望一屏向下滚动浏览Page 是更自然的选择。Page 和 Tab 可以嵌套比如 Page 里放一个柱状图再放一个包含散点图和饼图的 Tab 组件这样既能保持主线阅读节奏又能在局部做视图切换。5. 避坑与排查笔记pyecharts 可视化最常见的五个翻车点pyecharts 项目本身文档和源码都在持续更新但版本之间的行为差异不少。以下五条是我在多次重写这类项目时踩过、也帮别人排查过的坑按现象到原因再到解决的路子记录方便对照排查。5.1 图表渲染出空白页面浏览器控制台报 js 错误现象render() 之后 HTML 文件可以打开但图表区域是空白的控制台出现类似 “ECharts is not defined” 的报错。原因pyecharts 依赖的 echarts.min.js 是通过 CDN 加载的如果你在无外网环境或者 CDN 被拦截JS 文件就加载失败图表自然无法渲染。解决项目应内置一份 echarts.min.js在 InitOpts 里通过 js_host 参数指定本地路径。我通常把 echarts.min.js 下载到项目 assets 目录下然后统一设置 pyecharts 的全局配置。写作时需要去平台化所以这里不写外部链接只说明方法。5.2 add_yaxis 传入数据后柱状图顺序和预期相反现象原始数据明明按票房从高到低排好序画出来的柱状图却是从低到高。原因X 轴是类别轴pyecharts 默认按数据传入顺序绘制但如果传入的是 pandas 的 Index 对象且该 Index 是降序的再经过 sort_index() 操作后顺序会反转。解决先确认 add_xaxis 和 add_yaxis 传入两个列表的顺序是否一一对应打印前 10 条检查一遍。另一个隐蔽点是如果用 groupby 的结果直接传入groupby 默认会按键排序如果不想要默认排序加 sortFalse。排查时我在数据进入图表前加一个 zip 检查确保电影名和数值的对应关系没有错位。5.3 散点图上点全部挤在左下角现象散点图画出来后所有点都聚集在坐标轴左下角整个图几乎看不到分布趋势。原因数据量级差异过大票房从 1000 万到 50 亿都有如果 X 轴用线性刻度小票房电影全部被压缩到左边一窄条。解决X 轴改为对数刻度。pyecharts 的 AxisOpts 里设置 type_log它会自动调整刻度标签格式让低票房区域的点也能有视觉宽度。对数刻度下工具提示里的数值仍然是原始值不影响阅读。同理评分人数映射气泡大小之前也做了 log10 处理就是为了避免同样的挤压问题。5.4 地图类图表缺失数据无法显示现象有人尝试用 Map 做各省票房分布但地图渲染后只有零散几个省份有颜色。原因地图 JSON 数据只包含省份名称而我们的数据里的省份字段可能是“广东”“广东省”或者“广东(含深圳)”这样带后缀的写法名称对不上就匹配失败。解决做映射表把数据字段统一到地图 JSON 使用的标准名称。pyecharts 的 Map 在注册地图数据时需要名称完全一致所以写一个省份名称对照表是必要步骤。更稳的做法是在清洗阶段就把地区字段统一为不带后缀的标准名称。5.5 Jupyter Notebook 里图表不显示现象同样的代码在 .py 脚本里运行正常放到 Jupyter Notebook 里执行却不显示图表。原因Notebook 需要单元格输出 HTML 才能渲染 pyecharts 图表直接运行 render() 只是保存了文件并不会在 Notebook 里展示。解决用 JupyterChart 或者直接把图表对象放在单元格最后一行让 Notebook 调用它的repr_html方法输出。pyecharts 从 1.x 版本开始支持在 Notebook 里直接展示但需要 notebookTrue 参数或者用 pyecharts.charts 里的 JupyterChart。如果还是无法显示检查 pyecharts 和 jupyter 相关库的版本匹配情况。6. 一个进阶技巧让评分字段对票房的可解释程度现出原形前面画的散点图可以直观看到票房和评分的关系但“看出来”和“量化出来”是两回事。最后一章分享一个我在看完散点图后必做的计算它可以让你在汇报时多一句有数据支撑的结论而不是只说“从图上可以看出”。这个技巧是分组相关性检验。把数据按票房高低分成四组前 25% 是高票房组后 25% 是低票房组中间两组依次排列。然后分别计算每组内部票房和评分的 Spearman 相关系数。为什么要用 Spearman 而不是 Pearson因为票房数据不是正态分布尾部很长Pearson 会受极端值影响非常大而 Spearman 只关心排序关系对极端值的容忍度高很多。如果高票房组内部的评分与票房相关性显著为正说明口碑对票房有正向促进作用如果低票房组的评分显著高于高票房组说明存在“口碑好但票房差”的遗珠这类电影往往是宣发不足或档期竞争激烈造成的。from scipy.stats import spearmanr def analyze_correlation_by_group(df: pd.DataFrame) - None: df_sorted df.sort_values(总票房(万元), ascendingFalse).reset_index(dropTrue) n len(df_sorted) groups { 高票房组: df_sorted.iloc[:n // 4], 中高票房组: df_sorted.iloc[n // 4: n // 2], 中低票房组: df_sorted.iloc[n // 2: 3 * n // 4], 低票房组: df_sorted.iloc[3 * n // 4:], } for name, group in groups.items(): if len(group) 10: print(f{name}: 样本量不足跳过) continue rho, p_value spearmanr(group[总票房(万元)], group[豆瓣评分]) significance 显著 if p_value 0.05 else 不显著 print(f{name}: Spearman rho{rho:.3f}, p{p_value:.3f}, 相关性{significance}) analyze_correlation_by_group(cleaned)这个函数输出的是四个相关系数和对应的显著性水平。看结果时如果高票房组 rho 为正且 p 0.05说明头部电影确实存在“叫好又叫座”的现象如果高票房组 rho 接近零甚至为负说明票房和口碑在头部区间没有关系可能存在圈层消费或宣发主导的情况。这时候回到 pyecharts 的散点图把视觉映射 dimension 调整为按异常标记着色你会看到高票房组里确实有一批评分偏低的点在右上角说明它们的票房是其他因素驱动的。这么做下来你的分析就不再是画几张图了而是形成了一个“数据清洗 → 可视化观察 → 统计验证”的闭环。这是我在反复做类似项目后逐渐养成的习惯每张图都要追问它想验证什么假设画完之后用数值校验直觉。希望这个技巧能帮你在做自己的票房评分分析时快速找到真正值得深入的切入点。本文还有配套的精品资源点击获取
返回列表