matplotlib.patches.rectangle 如何在矩形中添加维度坐标而不是常规图形坐标

How to add dimension coordinates instead of regular graphs coordinates in Rectangles in matplotlib.patches.rectangle


我正在使用 matplotlib.patches.Rectangle 绘制多个矩形。我需要为每个添加维度。我需要提及每个矩形的尺寸,而不是图形的常规 X 坐标。在给定的图片中,我需要在边界处显示 x 坐标,而不是标准的 250、500、750..

part1 = matplotlib.patches.Rectangle((ip.iloc[i,7], ip.iloc[i,8]), ip.iloc[i,3], ip.iloc[i,4], color =np.random.rand(3)) 
ax.add_patch(part1)
plt.text(ip.iloc[i,7]+(0.5*ip.iloc[i,4]), (ip.iloc[i,8]+(0.5*ip.iloc[i,3])),ip.iloc[i,0],rotation='vertical', color = 'white',fontsize=8)

案例 1:单组

如果你有一个 ip 数据框,其中有一个 'x' 和一个 'y' 列,你的矩形的坐标属于一个组,你可以用 ax.set_xticks(ip['x'])ax.set_yticks(ip['y'])。通过这种方式,您将获得所有报价,除了您必须包含在 max(ip['x']) + ip.iloc[np.argmax(ip['x']), ip.columns.get_loc('width')]max(ip['y']) + ip.iloc[np.argmax(ip['y']), ip.columns.get_loc('height')].
中的最后一个报价 对于您的 ip 数据框,这些列应该是第 8 个(7 python 索引)和第 9 个(8 python 索引)列。检查下面的代码作为参考。

代码

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

ip = pd.DataFrame({'x': [0, 260, 520, 0, 260, 520],
                   'y': [0, 0, 0, 120, 120, 120],
                   'width': [260, 260, 230, 260, 260, 230],
                   'height': [120, 120, 120, 130, 130, 130],
                   'text': np.random.randint(0, 1000, 6)})

fig, ax = plt.subplots()

for i in range(len(ip)):
    part1 = matplotlib.patches.Rectangle((ip.iloc[i,0], ip.iloc[i,1]), ip.iloc[i,2], ip.iloc[i,3], color=np.random.rand(3))
    ax.add_patch(part1)
    plt.text(ip.iloc[i,0]+(0.5*ip.iloc[i,2]), (ip.iloc[i,1]+(0.5*ip.iloc[i,3])), ip.iloc[i,4], rotation='vertical', color='white', fontsize=8)

xticks = list(ip['x'])
xticks.append(max(ip['x']) + ip.iloc[np.argmax(ip['x']), ip.columns.get_loc('width')])
yticks = list(ip['y'])
yticks.append(max(ip['y']) + ip.iloc[np.argmax(ip['y']), ip.columns.get_loc('height')])
ax.set_xticks(xticks)
ax.set_yticks(yticks)

ax.set_xlim([min(ip['x']), max(ip['x']) + ip.iloc[np.argmax(ip['x']), ip.columns.get_loc('width')]])
ax.set_ylim([min(ip['y']), max(ip['y']) + ip.iloc[np.argmax(ip['y']), ip.columns.get_loc('height')]])
plt.show()

数据框

     x    y  width  height  text
0    0    0    260     120   372
1  260    0    260     120   543
2  520    0    230     120   174
3    0  120    260     130   140
4  260  120    260     130    27
5  520  120    230     130   800

结果


案例 2:双组

如果您有两组不同的区域,如图像所示,一组在 y 上低于 300,另一组高于此阈值,您可以复制 x 轴,以便在底轴上有较低的刻度(ax1) 和顶轴上的上刻度 (ax2)。检查下面的代码以供参考。
请注意,我在这里使用了不同的方法来简化代码和提高可读性。

代码

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

ip = pd.DataFrame({'x': [0, 260, 520, 0, 260, 520, 0, 250, 500, 0],
                   'y': [0, 0, 0, 120, 120, 120, 300, 300, 300, 410],
                   'width': [260, 260, 230, 260, 260, 230, 200, 170, 150, 250],
                   'height': [120, 120, 120, 130, 130, 130, 110, 110, 110, 120],
                   'text': np.random.randint(0, 1000, 10)})

fig, ax1 = plt.subplots()
ax2 = ax1.twiny()

for i in range(len(ip)):
    part1 = matplotlib.patches.Rectangle((ip.iloc[i,0], ip.iloc[i,1]), ip.iloc[i,2], ip.iloc[i,3], color=np.random.rand(3))
    ax1.add_patch(part1)
    ax1.text(ip.iloc[i,0]+(0.5*ip.iloc[i,2]), (ip.iloc[i,1]+(0.5*ip.iloc[i,3])), ip.iloc[i,4], rotation='vertical', color='white', fontsize=8)

lower_ip = ip[ip['y'] < 300]
upper_ip = ip[ip['y'] >= 300]

xticks1 = list(lower_ip['x'] + lower_ip['width']) # select the right-side limit of each lower area
xticks1.extend(lower_ip['x'])                     # add the left-side limit of each lower area
xticks1 = set(xticks1)                            # filter by unique values
xticks1 = list(xticks1)                           # convert back to list
xticks1.sort()                                    # sort in increasing order

xticks2 = list(upper_ip['x'] + upper_ip['width']) # select the right-side limit of each upper area
xticks2.extend(upper_ip['x'])                     # add the left-side limit of each upper area
xticks2 = set(xticks2)                            # filter by unique values
xticks2 = list(xticks2)                           # convert back to list
xticks2.sort()                                    # sort in increasing order

# set equal min value for both axes
if xticks1[0] > xticks2[0]:
    xticks2.append(xticks1[0])
elif xticks1[0] < xticks2[0]:
    xticks1.append(xticks2[0])

# set equal max value for both axes
if xticks1[-1] > xticks2[-1]:
    xticks2.append(xticks1[-1])
elif xticks1[-1] < xticks2[-1]:
    xticks1.append(xticks2[-1])

# set lower and upper x ticks
ax1.set_xticks(xticks1)
ax2.set_xticks(xticks2)

yticks = list(ip['y'] + ip['height']) # select the down-side limit of each area
yticks.extend(ip['y'])                # add the up-side limit of each area
yticks = set(yticks)                  # filter by unique values
yticks = list(yticks)                 # convert back to list
yticks.sort()                         # sort in increasing order
ax1.set_yticks(yticks)                # set y ticks

ax1.set_xlim([min(ip['x']), max(ip['x']) + ip.iloc[np.argmax(ip['x']), ip.columns.get_loc('width')]])
ax1.set_ylim([min(ip['y']), max(ip['y']) + ip.iloc[np.argmax(ip['y']), ip.columns.get_loc('height')]])
plt.show()

数据框

     x    y  width  height  text
0    0    0    260     120   457
1  260    0    260     120   217
2  520    0    230     120   467
3    0  120    260     130   495
4  260  120    260     130   941
5  520  120    230     130   998
6    0  300    200     110    50
7  250  300    170     110   623
8  500  300    150     110   934
9    0  410    250     120   366

结果