CASE 1: SINGLE GROUP
If you have a ip dataframe with a 'x' and a 'y' columns with the coordinates of your rectangles which belong to a single group, you can set your ticks with ax.set_xticks(ip['x']) and ax.set_yticks(ip['y']). In this way you will get all ticks, except the last one which you have to include with max(ip['x']) + ip.iloc[np.argmax(ip['x']), ip.columns.get_loc('width')] and max(ip['y']) + ip.iloc[np.argmax(ip['y']), ip.columns.get_loc('height')].
With your ip dataframe, those columns should be the 8th (7 python index) and the 9th (8 python index) ones. Check the code below as a reference.
Code
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()
Dataframe
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
Result

CASE 2: DOUBLE GRUOP
If you have two different groups of areas, as in your image, one below 300 on y and the other above this threshold, you can duplicate the x axis in order to have the lower ticks on the bottom axis (ax1) and the upper ticks on the top axis (ax2). Check the code below for reference.
Please, note that here I used a different approach in order to simplify a bit the code and the readability.
Code
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()
Dataframe
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
Result
