【问题标题】:Squarify treemap — How to add legend for rectangles that are too small?Squarify treemap - 如何为太小的矩形添加图例?
【发布时间】:2021-05-17 21:14:46
【问题描述】:

我的树形图有一个矩形太小而无法容纳其标签,因此我需要将树形图中的标签移到图例中。我正在使用norm_x,因为我正在尝试模拟温度计式绘图。下面看一下代码和别扭的标签:

sizes = [30, 15, 3]
        
labels = [
    'Largest Block\n(30 units)',
    'Second Largest Block\n(15 units)',
    'Small Block\n(3 units)'
]     
            
tmap = squarify.plot(
    sizes,
    label=labels,
    alpha=.7,
    norm_x=10,
)

tmap.axes.get_xaxis().set_visible(False)
    
plt.legend(labels)

产生:

当我添加 plt.legend(labels)(并从 squarify 调用中删除标签)时,我得到的图例只有一个标签:

所以我只需要找到一种方法将绘图中的所有标签添加到图例中。 matplotlib 文档建议我可能需要在plt.legend() 调用中添加三位艺术家,但我不确定在这种情况下如何执行此操作。此外,如果您有比创建图例更好的想法来解决此问题,那可能是一个更好的答案。

【问题讨论】:

    标签: python matplotlib legend treemap squarify


    【解决方案1】:

    矩形一起存储在BarContainer 中。默认情况下,matplotlib 为整个容器假设一个图例标签。要为每个单独的矩形添加图例标签,您可以将 BarContainer 作为句柄传递给 plt.legend()

    下面的示例代码明确指定了颜色,因为默认颜色可能有点难以区分。

    from matplotlib import pyplot as plt
    import squarify
    
    sizes = [30, 15, 3]
    labels = ['Largest Block\n(30 units)', 'Second Largest Block\n(15 units)', 'Small Block\n(3 units)']
    
    ax = squarify.plot(sizes, alpha=.7, norm_x=10, color=plt.cm.Set2.colors)
    ax.get_xaxis().set_visible(False)
    from matplotlib import pyplot as plt
    import squarify
    
    sizes = [30, 15, 3]
    labels = ['Largest Block\n(30 units)', 'Second Largest Block\n(15 units)', 'Small Block\n(3 units)']
    
    ax = squarify.plot(sizes, norm_x=10, color=plt.cm.Set2.colors)
    ax.get_xaxis().set_visible(False)
    
    plt.legend(handles=ax.containers[0], labels=labels)
    plt.show()
    

    PS:要使图例与显示的矩形顺序相同,您可以反转 y 轴 (ax.invert_yaxis()) 或反转句柄和标签列表 (plt.legend(handles=ax.containers[0][::-1], labels=labels[::-1]))。

    这里是另一个例子,注释图中最大的矩形并在图例中显示最小的矩形:

    from matplotlib import pyplot as plt
    import squarify
    import numpy as np
    
    labels = [55, 34, 21, 13, 8, 5, 3, 2, 1, 1]
    sizes = [f * f for f in labels]
    num_labels_in_legend = 5
    
    ax = squarify.plot(sizes, label=labels[:-num_labels_in_legend], color=plt.cm.plasma(np.linspace(0, 1, len(labels))),
                       ec='black', norm_x=144, norm_y=89, text_kwargs={'color': 'white', 'size': 18})
    ax.axis('off')
    ax.invert_xaxis()
    ax.set_aspect('equal')
    plt.legend(handles=ax.containers[0][:-num_labels_in_legend - 1:-1], labels=labels[:-num_labels_in_legend - 1:-1],
               handlelength=1, handleheight=1)
    plt.show()
    

    这是一个计算要在图例中显示的标签数量的想法。例如,当小矩形的总面积小于总面积的 5% 时:

    num_labels_in_legend = np.count_nonzero(np.cumsum(sizes) / sum(sizes) > 0.95)
    

    或者只是小于总面积 2% 的矩形数量:

    num_labels_in_legend = np.count_nonzero(np.array(sizes) / sum(sizes) < 0.02)
    

    【讨论】:

    • 很好的答案;我正要添加handles=ax.containers[0][::-1] 以供订购。您是否认为有一种方法可以自动确定移动到图例的标签数量,而不是硬编码? (我正在制作的情节是一个自动脚本,所以我无法将它从使用更改为使用。)
    • 我刚刚添加了一个可能的公式。
    猜你喜欢
    • 1970-01-01
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多