Squarify treemap - 如何为太小的矩形添加图例?

问题描述

我的树状图有一个矩形,该矩形太小而无法容纳其标签,因此我需要将标签从树状图中移到图例中。我使用 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)

产生:

enter image description here

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

enter image description here

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

解决方法

矩形一起存储在 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,color=plt.cm.Set2.colors)
ax.get_xaxis().set_visible(False)

plt.legend(handles=ax.containers[0],labels=labels)
plt.show()

resulting plot

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,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()

second example

这是计算图例中显示的标签数量的想法。例如当小矩形的总面积小于总面积的 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)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...