我正在试着创造一个类似于this one的情节.条形图和框图重叠的镶嵌面栅格.这些数据存储在Pandas 的数据帧中.我与引用的问题的不同之处在于,除了沿X轴分布条形图之外,我还通过hue参数 for each X值绘制多个条形图(和点条形图).到目前为止,一切都很顺利,这是可行的.

问题是,盒子和点带没有对齐它们的垂直位置,如图中第一列的上行以及第二列和最后一列的下行所示.相应的盒子和点带大多彼此相邻,甚至具有不同的偏移量.

Boxes and Points do not always align

以下是我到目前为止使用虚拟数据集编写的代码:

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np

################### generate dummy data set ###################
np.random.seed(20240224)
numPoints = 300 # should be divisible by 3 and 2
df = pd.DataFrame({"CategoryX": np.random.randint(1, 4, numPoints),
                   "CategoryY": np.random.rand(numPoints),
                   # the imbalance here seems to be the problem trigger
                   "CategoryColor": np.random.choice([0,1,2,3], size=numPoints, p=[0.33, 0.33, 0.33, 0.01]),
                   "CategoryColumn": np.array(["ColA", "ColB", "ColC"] * (numPoints // 3)),
                   "CategoryRow": np.array(["RowA"] * (numPoints // 2) + ["RowB"] * (numPoints // 2)),
                   })

################### actual plot ###################

commonParams = dict(
    x="CategoryX",
    y="CategoryY",
    hue="CategoryColor",
)

g = sns.catplot(
    data=df,
    **commonParams,
    col="CategoryColumn",
    row="CategoryRow",
    kind="strip",
    dodge=True,
)

# map by hand bc I couldn't figure out how to properly use map() or map_dataframe()
for i, s in enumerate(df['CategoryColumn'].unique()):
    for j, f in enumerate(df['CategoryRow'].unique()):
        sns.boxplot(
            data=df[(df['CategoryColumn'] == s) & (df['CategoryRow'] == f)],
            **commonParams,
            ax=g.axes[j, i],        # draw on the existing axes
            legend=False,
        )

bad alignment sns.catplot and boxplots

任何帮助将其整齐地排列在彼此之上的人都将非常感激!

推荐答案

感谢您提供可复制的数据.

显然,只有当行名或列名是数字时,才会得到顺序上的差异.此外,当其中一个子图缺少一些色调值时,箱图(或任何类似的曲线图)将被分配,而不计算该色调值.逐个打印时,Seborn仅看到子图的色调值.

为了减轻这种情况,类别列可以由类型pd.Categorical组成,这强制使用一组固定的色调值,即使某些色调值缺失. 请注意,这也将默认值palette更改为tab10.如果需要,palette可以显式设置为flare.

(我也测试了hue_order,但这只有在您还设置了相同 colored颜色 数量的调色板时才起作用,不幸的是,这会弄乱图形图例.使用Seborn 0.13.2和Pandas 2.2.1进行测试)

下面是该示例的外观:


# change the column from numeric to pd.Categorical
df["CategoryColor"] = pd.Categorical(df["CategoryColor"])

commonParams = dict(
    x="CategoryX",
    y="CategoryY",
    hue="CategoryColor",
    palette='flare',
)

g = sns.catplot(
    data=df,
    **commonParams,
    col="CategoryColumn",
    row="CategoryRow",
    kind="strip",
    dodge=True,
)

for (row, col), ax in g.axes_dict.items():
    sns.boxplot(
        data=df[(df['CategoryColumn'] == col) & (df['CategoryRow'] == row)],
        **commonParams,
        ax=ax,  # draw on the existing axes
        legend=False,
        boxprops={'alpha': 0.7} # transparency to see stripplot
    )
plt.show()

combining catplot with boxplots using g.axes_dict

Python相关问答推荐

pandas DataFrame GroupBy.diff函数的意外输出

时间序列分解

Python上的Instagram API:缺少client_id参数"

scikit-learn导入无法导入名称METRIC_MAPPING64'

从一个系列创建一个Dataframe,特别是如何重命名其中的列(例如:使用NAs/NaN)

在极性中创建条件累积和

在vscode上使用Python虚拟环境时((env))

在含噪声的3D点网格中识别4连通点模式

在代码执行后关闭ChromeDriver窗口

OpenGL仅渲染第二个三角形,第一个三角形不可见

根据客户端是否正在传输响应来更改基于Flask的API的行为

无法在Spyder上的Pandas中将本地CSV转换为数据帧

在Python中控制列表中的数据步长

jsonschema日期格式

python的文件. truncate()意外地没有截断'

递归链表反转与打印语句挂起

如何在PYTHON中向单元测试S Side_Effect发送额外参数?

利用广播使减法更有效率

基于2级列表的Pandas 切片3级多索引

`Convert_time_zone`函数用于根据为极点中的每一行指定的时区检索值