add_patch 在箱线图中使用 matplotlib (python)

add_patch in boxplot with matplotlib (python)

我正在做一个混合了热图的自定义箱线图,在我的 matplotlib 中发现了一个奇怪的东西。添加补丁 (ax.add_patch) 时,补丁矩形在使用 rect.get_verts() 时给出不同的顶点。

我的想法是垂直分割我的箱线图,以便在 IQR 内添加颜色,即 IQR 从 [2,6] 开始,每个统一,([3,4[;[4,5[;[ 5,6[) 将具有基于其他变量的颜色。

我认为最简单的方法是获取代表盒子的面片,获取顶点,将高度除以单位数,然后创建每个面片来绘制它。

添加矩形之前

Patch [[ 610.2 1684.8]
 [ 610.7 1684.8]
 [ 610.7 1685.8]
 [ 610.2 1685.8]
 [ 610.2 1684.8]]

添加矩形后

Patch [[408697.92  549568.368]
 [409032.72  549568.368]
 [409032.72  549894.528]
 [408697.92  549894.528]
 [408697.92  549568.368]]

因此该图毫无意义,因为代码都在左边,y(位于 0,80 之间)一直到 2000。

这是我目前的做法:

bplot = ax.bxp(y,patch_artist=True)

for patch,q1,q3,label in zip(bplot['boxes'] data_box["q1"],data_box["q3"],data_box["label"]):
    print(f"Label {label}")

    verts = patch.get_verts().copy()
    print(f"Verts : {verts}")
    height = (verts[3] - verts[0]).sum()
    width = (verts[1] - verts[0]).sum()


 
    height_per_unit = height/(q3-q1)

    initial_verts = verts[0].copy()
    for i in range(int(q3-q1)):
        
        rect = patches.Rectangle((initial_verts[0],initial_verts[1]),0.5, 1)
        rectangles.append(rect)
        print(f"Patch {rect.get_verts()}\n" )
        ax.add_patch(rect)
        initial_verts = rect.get_verts()[3] 

有谁知道如何解决这个问题?

我明白了。我们需要考虑使用 ax.transAxes.inversed().transform() 之前和之后的转换,即

for patch,color,q1,q3,label in zip(bplot['boxes'],data_box['Color'], data_box["q1"],data_box["q3"],data_box["label"]):
    # print(f"Label {label}")

    verts = patch.get_verts().copy()

    # WE USE HERE FIRST
    verts = ax.transAxes.inverted().transform(verts) 

    print(f"Verts : {verts}")
    height = (verts[3] - verts[0]).sum()
    width = (verts[1] - verts[0]).sum()

    # print(f"Height : {height}\nWidth:{width}")
    
    height_per_unit = height/(q3-q1)
    # print(f"Height per unit : {height_per_unit}")7
    
    initial_verts = verts[0].copy()
    print(initial_verts)
    
    
    for i in range(int(q3-q1)):
       
        rect = patches.Rectangle((initial_verts[0],initial_verts[1]),0.5, 1, zorder=1000)
        rectangles.append(rect)
        
        print(f"Patch {rect.get_verts()}\n" )
        ax.add_patch(rect)

        # THEN WE USE HERE
        initial_verts = ax.transAxes.inverted().transform(rect.get_verts())[3]