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
结果
我正在使用 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