Matplotlib_Venn, 多个维恩图相同比例
Matplotlib_Venn, Multiple Venn diagrams same scale
我目前有一个包含 5 个维恩图子图的图形。所有 5 个图表都是 2 个圆维恩,每个都有不同的元素总和。Refer to this figure。
我想知道是否可以将这 6 个子图都设置为相同的比例?例如,我的整个第一个维恩会被缩放到小于第五个。
代码如下。
非常感谢任何帮助。
from matplotlib_venn import venn2
from matplotlib import pyplot as plt
import numpy as np
figure, axes = plt.subplots(2, 3, figsize=(11.69,8.27))
BSL_20=(313,10,76)
BSL_40=(384,17,150)
BSL_100=(665,8,378)
BSL_100CC=(860,23,879)
BSL_200=(585,17,758)
v1=venn2(BSL_20, set_labels = ('150mm at 50%', '400mm at 25%'), ax=axes[0][0])
v2=venn2(BSL_40, set_labels = ('150mm at 50%', '400mm at 25%'), ax=axes[0][1])
v3=venn2(BSL_100, set_labels = ('150mm at 50%', '400mm at 25%'), ax=axes[0][2])
v4=venn2(BSL_100CC, set_labels = ('150mm at 50%', '400mm at 25%'), ax=axes[1][0])
v5=venn2(BSL_200, set_labels = ('150mm at 50%', '400mm at 25%'), ax=axes[1][1])
v6=venn2(BSL_200, set_labels = ('150mm at 50%', '400mm at 25%'), ax=axes[1][1])
axes[1,2].axis('off')
plt.show()
尝试在 plt.show()
:
之前将其添加到您的代码中
from matplotlib.cbook import flatten
data = [BSL_20, BSL_40, BSL_100, BSL_100CC, BSL_200]
max_area = max(map(sum, data))
def set_venn_scale(ax, true_area, reference_area=max_area):
s = np.sqrt(float(reference_area)/true_area)
ax.set_xlim(-s, s)
ax.set_ylim(-s, s)
for a, d in zip(flatten(axes), data):
set_venn_scale(a, sum(d))
解释:
matplotlib_venn
绘制的图块已按比例缩放,因此它们的总面积为 1。图表的中心位于点 (0, 0) 附近,并配置了轴限制,以便图表适合紧紧地在里面。
- 这意味着如果您简单地为所有子图设置
xlim(-1, 1)
和 ylim(-1, 1)
,您将得到总面积相同的图表(假设所有子图都以相同的比例显示).
- 如果您现在需要 "scale down" 其中一个图表以将其面积减少 2,实现它的一种方法是简单地将所有轴限制放大
sqrt(2)
。
- 上面的代码就是这样做的:它首先识别出实际总面积最大的圆集,然后简单地将其他图的范围按比例放大到
sqrt(max_area/required_area)
。
您还可以减少 Y 轴上的一些松弛部分,并将代码和图表打包得更紧,如下所示:
from matplotlib_venn import venn2
from matplotlib.cbook import flatten
from matplotlib import pyplot as plt
import numpy as np
figure, axes = plt.subplots(2, 3, figsize=(11.69,5.5))
BSL_20=(313,10,76)
BSL_40=(384,17,150)
BSL_100=(665,8,378)
BSL_100CC=(860,23,879)
BSL_200=(585,17,758)
data = [BSL_20, BSL_40, BSL_100, BSL_100CC, BSL_200]
max_area = max(map(sum, data))
def set_venn_scale(vd, ax, true_area, reference_area=max_area):
sx = np.sqrt(float(reference_area)/true_area)
sy = max(vd.radii)*1.3
ax.set_xlim(-sx, sx)
ax.set_ylim(-sy, sy)
for a, d in zip(flatten(axes), data):
vd = venn2(d, set_labels = ('150mm at 50%', '400mm at 25%'), ax=a)
set_venn_scale(vd, a, sum(d))
axes[1,2].axis('off')
figure.tight_layout(pad=0.1)
plt.show()
请注意,如果 tight_layout
感觉不够 space,它会开始重新缩放您的子图,因此请检查结果(例如,通过 [=19= 在您的子图周围添加轴] 并确保所有子图具有相同的宽度)。
我目前有一个包含 5 个维恩图子图的图形。所有 5 个图表都是 2 个圆维恩,每个都有不同的元素总和。Refer to this figure。
我想知道是否可以将这 6 个子图都设置为相同的比例?例如,我的整个第一个维恩会被缩放到小于第五个。
代码如下。 非常感谢任何帮助。
from matplotlib_venn import venn2
from matplotlib import pyplot as plt
import numpy as np
figure, axes = plt.subplots(2, 3, figsize=(11.69,8.27))
BSL_20=(313,10,76)
BSL_40=(384,17,150)
BSL_100=(665,8,378)
BSL_100CC=(860,23,879)
BSL_200=(585,17,758)
v1=venn2(BSL_20, set_labels = ('150mm at 50%', '400mm at 25%'), ax=axes[0][0])
v2=venn2(BSL_40, set_labels = ('150mm at 50%', '400mm at 25%'), ax=axes[0][1])
v3=venn2(BSL_100, set_labels = ('150mm at 50%', '400mm at 25%'), ax=axes[0][2])
v4=venn2(BSL_100CC, set_labels = ('150mm at 50%', '400mm at 25%'), ax=axes[1][0])
v5=venn2(BSL_200, set_labels = ('150mm at 50%', '400mm at 25%'), ax=axes[1][1])
v6=venn2(BSL_200, set_labels = ('150mm at 50%', '400mm at 25%'), ax=axes[1][1])
axes[1,2].axis('off')
plt.show()
尝试在 plt.show()
:
from matplotlib.cbook import flatten
data = [BSL_20, BSL_40, BSL_100, BSL_100CC, BSL_200]
max_area = max(map(sum, data))
def set_venn_scale(ax, true_area, reference_area=max_area):
s = np.sqrt(float(reference_area)/true_area)
ax.set_xlim(-s, s)
ax.set_ylim(-s, s)
for a, d in zip(flatten(axes), data):
set_venn_scale(a, sum(d))
解释:
matplotlib_venn
绘制的图块已按比例缩放,因此它们的总面积为 1。图表的中心位于点 (0, 0) 附近,并配置了轴限制,以便图表适合紧紧地在里面。- 这意味着如果您简单地为所有子图设置
xlim(-1, 1)
和ylim(-1, 1)
,您将得到总面积相同的图表(假设所有子图都以相同的比例显示). - 如果您现在需要 "scale down" 其中一个图表以将其面积减少 2,实现它的一种方法是简单地将所有轴限制放大
sqrt(2)
。 - 上面的代码就是这样做的:它首先识别出实际总面积最大的圆集,然后简单地将其他图的范围按比例放大到
sqrt(max_area/required_area)
。
您还可以减少 Y 轴上的一些松弛部分,并将代码和图表打包得更紧,如下所示:
from matplotlib_venn import venn2
from matplotlib.cbook import flatten
from matplotlib import pyplot as plt
import numpy as np
figure, axes = plt.subplots(2, 3, figsize=(11.69,5.5))
BSL_20=(313,10,76)
BSL_40=(384,17,150)
BSL_100=(665,8,378)
BSL_100CC=(860,23,879)
BSL_200=(585,17,758)
data = [BSL_20, BSL_40, BSL_100, BSL_100CC, BSL_200]
max_area = max(map(sum, data))
def set_venn_scale(vd, ax, true_area, reference_area=max_area):
sx = np.sqrt(float(reference_area)/true_area)
sy = max(vd.radii)*1.3
ax.set_xlim(-sx, sx)
ax.set_ylim(-sy, sy)
for a, d in zip(flatten(axes), data):
vd = venn2(d, set_labels = ('150mm at 50%', '400mm at 25%'), ax=a)
set_venn_scale(vd, a, sum(d))
axes[1,2].axis('off')
figure.tight_layout(pad=0.1)
plt.show()
请注意,如果 tight_layout
感觉不够 space,它会开始重新缩放您的子图,因此请检查结果(例如,通过 [=19= 在您的子图周围添加轴] 并确保所有子图具有相同的宽度)。