Plotly直方图为不同类别柱子设置自定义颜色后统计结果异常的技术咨询
嘿,这个问题我碰到过!让我给你拆解一下为啥会这样,还有怎么解决~
问题原因分析
当你给px.histogram加上color="result"参数后,Plotly会自动把数据按result的两个类别拆分成独立的trace(轨迹)。这时候histnorm='probability density'的归一化逻辑就变了:它不再基于整个数据集的总数来计算密度,而是对每个单独的trace(也就是每个类别自己的数据集)做归一化。因为每个trace里只有同一种类别的数据,归一化后该类别的密度自然就是1,所以两个柱子都显示成1了,完全偏离了真实的分布比例。
两种解决方案
方案1:先统计分布,用条形图绘制(推荐,更适合类别变量)
对于只有两类的类别变量,其实用条形图比直方图更直观,而且能完美解决颜色和统计的问题。我们先手动计算每个类别的概率密度,再用px.bar绘图:
import pandas as pd import plotly.express as px # 你的原始数据 hist_data = ['no disease', 'cardiovascular disease', 'no disease', 'no disease', 'cardiovascular disease', 'cardiovascular disease', 'cardiovascular disease', 'cardiovascular disease', 'cardiovascular disease', 'no disease'] # 转成DataFrame并统计分布 df = pd.DataFrame(hist_data, columns=['result']) count_df = df['result'].value_counts().reset_index() count_df.columns = ['result', 'count'] # 计算全局概率密度 total_samples = count_df['count'].sum() count_df['prob_density'] = count_df['count'] / total_samples # 绘制条形图,设置自定义颜色 fig = px.bar( count_df, x="result", y="prob_density", color="result", color_discrete_map={ 'no disease': '#636EFA', # 自定义蓝色 'cardiovascular disease': '#EF553B' # 自定义橙色 } ) # 调整y轴标题 fig.update_layout(yaxis_title="Probability Density") fig.show()
方案2:保留直方图,手动修改柱子颜色
如果你坚持要用直方图,可以回到最初的正确统计代码,然后手动给两个柱子设置不同颜色,避免拆分trace导致的归一化问题:
import pandas as pd import plotly.express as px hist_data = ['no disease', 'cardiovascular disease', 'no disease', 'no disease', 'cardiovascular disease', 'cardiovascular disease', 'cardiovascular disease', 'cardiovascular disease', 'cardiovascular disease', 'no disease'] df = pd.DataFrame(hist_data, columns=['result']) # 初始正确统计的直方图代码 fig = px.histogram( df, x="result", histfunc='count', histnorm='probability density' ) # 手动给两个柱子设置颜色 fig.update_traces( marker_color=['#636EFA', '#EF553B'], # 对应两个类别的颜色 selector=dict(type='histogram') ) fig.show()
这样既保留了正确的分布统计,又实现了不同类别不同颜色的需求。
内容的提问来源于stack exchange,提问作者Vitto
相关产品推荐
相关产品推荐

