我在Squarify的文档中找不到一种方法来编辑树状图中矩形的形状。我想将其中一个矩形显示为另一个矩形的正方形子集。这是我目前所拥有的:
import squarify
from matplotlib import pyplot as plt
treemap_df = pd.DataFrame({
'names': ['A', 'B', 'C'],
'sizes': [25, 50, 75]
})
plt.figure(figsize=(10, 4))
ax = squarify.plot(
treemap_df.sizes,
label=treemap_df.names,
color=["red","green","grey"],
alpha=.8,
edgecolor="white",
linewidth=4
)
# I can get the coordinates of the squares/patches like this:
for rect in ax.patches:
x, y, w, h = rect.get_x(), rect.get_y(), rect.get_width(), rect.get_height()
c = rect.get_facecolor()
print(f'Rectangle x={rect.get_x()} y={rect.get_y()} w={rect.get_width()} h={rect.get_height()} ')
plt.axis('off')
plt.title('Basic Treemap')
plt.show()这为我提供了以下输出:

所以,假设我只想编辑绘图,这样矩形'A‘就是一个正方形--有没有办法做到这一点?理想情况下,我希望'B‘的形状甚至不是正方形,而是看起来'A’是矩形'B‘的内嵌(这样在实际的轮廓线中就会有一个L形状),但只要能够调整矩形的形状/位置就很好了。谢谢。
发布于 2021-02-09 07:52:29
下面的方法首先循环遍历矩形并保存矩形A和B的位置。
然后,将A的宽度和高度修改为其乘积的平方根。
基于A和B的坐标并复制B的属性,创建了一个新的L形多边形。然后,删除B。
请注意,以下代码仅适用于A和B的特定位置。其他位置需要一点不同的L型,或者可能是不可能的。
另请注意,要使正方形看起来像正方形,需要相等的纵横比。Squarify使用参数norm_x和norm_y,缺省为100,这是周围矩形的尺寸。您可以将它们更改为具有不同的纵横比,但请注意,这可能会更改生成的矩形的位置。
import squarify
from matplotlib import pyplot as plt
from matplotlib.patches import Polygon
from math import sqrt
names = ['A', 'B', 'C']
sizes = [25, 50, 75]
plt.figure(figsize=(8, 6))
ax = squarify.plot(
sizes,
norm_x=100,
norm_y=100,
label=names,
color=["red", "green", "grey"],
alpha=.8,
edgecolor="white",
linewidth=4)
for rect, name in zip(ax.patches, names):
(x, y), w, h = rect.get_xy(), rect.get_width(), rect.get_height()
c = rect.get_facecolor()
print(f'Rectangle {name} x={rect.get_x()} y={rect.get_y()} w={rect.get_width()} h={rect.get_height()} ')
if name == 'A':
rect_for_square = rect
sq_size = sqrt(w * h)
xa, ya = x, y
if name == 'B':
rect_for_L = rect
xb, yb, wb, hb = x, y, w, h
rect_for_square.set_width(sq_size)
rect_for_square.set_height(sq_size)
points = [[xb, ya + sq_size], [xb, yb + hb], [xb + wb, yb + hb], [xb + wb, ya],
[xb + sq_size, ya], [xb + sq_size, ya + sq_size], [xb, ya + sq_size]]
poly_L = Polygon(points, closed=True)
poly_L.update_from(rect_for_L) # copy colors, alpha, linewidths, ...
ax.add_patch(poly_L)
rect_for_L.remove()
ax.set_aspect('equal')
plt.axis('off')
plt.show()

https://stackoverflow.com/questions/66105834
复制相似问题