【问题标题】:How to add dimension coordinates instead of regular graphs coordinates in Rectangles in matplotlib.patches.rectangle如何在 matplotlib.patches.rectangle 的矩形中添加维度坐标而不是常规图形坐标
【发布时间】:2020-08-02 08:32:36
【问题描述】:


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

【问题讨论】:

    标签: python matplotlib coordinates rectangles dimensions


    【解决方案1】:

    案例 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
    

    结果

    【讨论】:

    • 感谢您的帮助。我还有一个疑问。如果你参考我的图,有两组矩形。第二组从图中的 300 开始。我们可以修改 xticks 和 yticks 以分别显示第二个图形的 X 和 Y 坐标吗?希望我清楚我的问题?请帮忙。
    • 感谢您的出色回应。它真的帮助了我。但我还是有一些额外的疑问。我想在图表的 Y 侧以不同的方式标记这些牵引组。就像将它们命名为第一组的“SET-1”和第二组的“SET-2”。是否可以在图表的 Y 侧创建 2 个不同的文本框?
    • 是的,您可以查看this answer 作为为轴标签添加和附加文本框的参考。如果您没有设法使该代码适应您的情况,我认为您应该打开另一个问题以保持该线程尽可能干净,因为此进一步查询不属于上述问题:-)
    • 当然明白。谢谢!!
    猜你喜欢
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多