Holoviews:在分组分类柱状图添加HLine时出现维度不匹配错误
问题原因及解决方案
错误原因
你混用了pandas的matplotlib绘图体系和holoviews图形元素,两者不属于同一绘图框架:
- pandas的
plot(kind='bar')返回的是matplotlib的Axes对象(2维绘图轴) hv.HLine是holoviews的独立图形元素(1维线元素)
直接用*叠加不同框架的对象,就会触发维度不匹配的错误。
解决方案
方案一:纯matplotlib/pandas实现(适配原代码习惯)
利用pandas绘图基于matplotlib的特性,直接通过轴对象添加均值线:
import pandas as pd import matplotlib.pyplot as plt Data_test = [['2010', 5, 'Yes'], ['2010', 7, 'No'], ['2011', 3, 'Yes'], ['2011', 5, 'No'], ['2012', 7, 'Yes'], ['2012', 3, 'No'], ['2013', 8, 'Yes'], ['2013', 7, 'No'], ['2014', 2, 'Yes'], ['2014', 3, 'No'], ['2015', 6, 'Yes'], ['2015', 7, 'No'], ['2016', 1, 'Yes'], ['2016', 7, 'No'], ['2017', 9, 'Yes'], ['2017', 3, 'No'], ['2018', 7, 'Yes'], ['2018', 5, 'No'], ['2019', 3, 'Yes'], ['2019', 9, 'No']] test_df = pd.DataFrame(Data_test, columns = ['Year', 'Value', 'Category']) # 先将分组数据unstack,生成正确的分组柱状图结构 ax = test_df.groupby(['Year', 'Category'])['Value'].mean().unstack().plot(kind='bar') # 计算整体均值 mean_val = test_df['Value'].mean() # 添加水平均值线,自定义样式 ax.axhline(y=mean_val, color='red', linestyle='--', label=f'整体均值: {mean_val:.2f}') # 显示图例 ax.legend() plt.show()
注:原代码中opts(multi_level=False)是holoviews的参数,对pandas绘图无效,这里通过unstack()将多级索引转为列,实现正确的分组柱状图。
方案二:纯holoviews实现(适配holoviews语法)
全程使用holoviews绘图,确保所有元素属于同一框架,可直接叠加:
import pandas as pd import holoviews as hv import numpy as np hv.extension('bokeh') # 可选'matplotlib'作为渲染后端 Data_test = [['2010', 5, 'Yes'], ['2010', 7, 'No'], ['2011', 3, 'Yes'], ['2011', 5, 'No'], ['2012', 7, 'Yes'], ['2012', 3, 'No'], ['2013', 8, 'Yes'], ['2013', 7, 'No'], ['2014', 2, 'Yes'], ['2014', 3, 'No'], ['2015', 6, 'Yes'], ['2015', 7, 'No'], ['2016', 1, 'Yes'], ['2016', 7, 'No'], ['2017', 9, 'Yes'], ['2017', 3, 'No'], ['2018', 7, 'Yes'], ['2018', 5, 'No'], ['2019', 3, 'Yes'], ['2019', 9, 'No']] test_df = pd.DataFrame(Data_test, columns = ['Year', 'Value', 'Category']) # 创建holoviews柱状图,聚合均值 bar_plot = hv.Bars(test_df, kdims=['Year', 'Category'], vdims='Value').aggregate(function=np.mean).opts(multi_level=False) # 创建均值水平线 mean_line = hv.HLine(test_df['Value'].mean()).opts(color='red', linestyle='--', label=f'整体均值: {test_df["Value"].mean():.2f}') # 叠加图形 test_plot = bar_plot * mean_line test_plot
内容的提问来源于stack exchange,提问作者Amen_1990
相关产品推荐
相关产品推荐

