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
相关产品推荐
相关产品推荐

