You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matplotlib马赛克图条形顺序在Jupyter正常但Plotly Dash异常

问题描述

我正在开发一个Python应用,使用Matplotlib生成马赛克图(mosaic plot)并嵌入Plotly Dash应用中。遇到的问题是:在Jupyter Notebook中运行代码时,马赛克图的条形顺序符合预期,但在Plotly Dash应用中运行相同代码时,条形顺序出现错误。

最小可复现示例

import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.graphics.mosaicplot import mosaic
from scipy.stats import chi2_contingency
import numpy as np
from io import BytesIO
import base64

# Create a sample DataFrame
data = {
    'adc1[SQ001]': ['1 time', '2 times', 'Never', 'more than 5 times', 'Never',
                     '3 times', 'Never', 'Never', 'Never', '1 time',
                     '1 time', 'Never', 'Never', '3 times', 'more than 5 times',
                     '1 time', 'more than 5 times', '1 time', 'Never', '4 times'],
    'CE11': ['Exact and Earth Sciences', 'Human Sciences', 'Health Sciences', 
             'Linguistics, Letters and Arts', 'Exact and Earth Sciences', 'Agrarian Sciences',
             'Biological Sciences', 'Exact and Earth Sciences', 'Agrarian Sciences',
             'Engineering', 'Health Sciences', 'Biological Sciences', 'Engineering',
             'Human Sciences', 'Biological Sciences', 'Exact and Earth Sciences',
             'Human Sciences', 'Agrarian Sciences', 'Health Sciences',
             'Exact and Earth Sciences']
}

df = pd.DataFrame(data)

# Define ordered categories
ordered_categories = ['Never', '1 time', '2 times', '3 times', '4 times', '5 times', 'more than 5 times']

# Convert the column to an ordered categorical type
df['adc1[SQ001]'] = pd.Categorical(df['adc1[SQ001]'], categories=ordered_categories, ordered=True)

# Create the contingency table
contingency_table = pd.crosstab(df['adc1[SQ001]'], df['CE11'], observed=False)
contingency_table = contingency_table.reindex(ordered_categories, axis=0)

# Calculate the chi-square test
chi2_stat, p, dof, expected = chi2_contingency(contingency_table)
residuals = (contingency_table - expected) / np.sqrt(expected)

# Function to map block colors based on Pearson residuals
def residual_color(key):
    if key[1] in residuals.index and key[0] in residuals.columns:
        value = residuals.loc[key[1], key[0]]
        if value >= 4:
            return {'color': 'red'}
        elif value >= 2:
            return {'color': 'lightcoral'}
        elif value <= -4:
            return {'color': 'blue'}
        elif value <= -2:
            return {'color': 'dodgerblue'}
        else:
            return {'color': 'lightgrey'}
    else:
        return {'color': 'lightgrey'}

# Create the mosaic plot
fig, ax = plt.subplots(figsize=(10, 6))
mosaic(df, ['CE11', 'adc1[SQ001]'], properties=residual_color, ax=ax, gap=0.02, labelizer=lambda k: '')

# Add a color legend for Pearson residuals
bounds = [-4, -2, 2, 4]
cmap = plt.cm.RdBu_r
norm = plt.Normalize(vmin=-4, vmax=4)

sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
cbar = plt.colorbar(sm, ax=ax, ticks=[-4, -2, 2, 4])
cbar.ax.set_yticklabels(['<= -4', '-2', '2', '>= 4'])
cbar.ax.text(0.5, -0.1, f'p-value: {p:.3f}', transform=cbar.ax.transAxes, fontsize=12, 
             verticalalignment='top', horizontalalignment='center', 
             bbox=dict(facecolor='white', edgecolor='black', boxstyle='round,pad=0.5'))

# Adjust x-axis labels
ax.set_xticklabels(ax.get_xticklabels(), rotation=45)

# Show the plot
plt.show()

具体问题

在Jupyter Notebook中,马赛克图的条形按ordered_categories指定的顺序正确排列;但在Plotly Dash应用中,条形顺序不符合预期。

已尝试的解决措施

  • 验证列已正确转换为带指定顺序的分类类型;
  • 基于ordered_categories重新索引列联表;
  • 检查Jupyter与Plotly应用的环境差异。

补充信息

Plotly应用通过Matplotlib生成图表,将其编码为base64图片后嵌入应用中。

疑问

为何在Plotly应用中运行时条形顺序不同?如何确保两种环境下马赛克图的条形顺序均正确?


内容的提问来源于stack exchange,提问作者Marcelo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 06:17:10