Matplotlib_Venn,多个维恩图相同比例

时间:2015-12-09 16:25:10

标签: python matplotlib venn-diagram matplotlib-venn

我目前有一个包含5个维恩图子图的图。所有5个图都是2个圆形的,每个都有不同的元素总和。Refer to this figure

我想知道是否可以将这6个子图全部放在相同的比例范围内?例如,我的整个第一个venn将缩放到小于第五个。

以下代码。 任何最感谢的帮助。

bool CUserTest::LogInUser()
{
    if ((m_hUserToken == NULL) && !LogonUser(TEST_USER_NAME, L".", TEST_USER_PASS, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &m_hUserToken))
    {
        CloseHandle(m_hUserToken);
        m_hUserToken = NULL;
    }
    return (m_hUserToken != NULL);
}

bool CUserTest::LaunchTestApp()
{
   PROCESS_INFORMATION ProcInfo;
   STARTUPINFO si;
   ZeroMemory(&si, sizeof(STARTUPINFO));
   si.cb = sizeof(si);
   si.lpDesktop = L"winsta0\\default";
   wchar_t wszCmdLine[MAX_PATH + 1] = { 0 };
   wcscpy(wszCmdLine, L"UserTestClient.exe");

   bool bSuccess = false;

   LPVOID pEnv;
   PROFILEINFO sProfileInfo;
   ZeroMemory(&sProfileInfo, sizeof(PROFILEINFO));
   sProfileInfo.dwSize = sizeof(PROFILEINFO);
   sProfileInfo.lpUserName = TEST_USER_NAME;
   if (LoadUserProfile(m_hUserToken, &sProfileInfo))
   {
       if (ImpersonateLoggedOnUser(m_hUserToken))
       {
           if (CreateEnvironmentBlock(&pEnv, m_hUserToken, FALSE))
           {
               bSuccess = CreateProcessAsUser(
                   m_hUserToken,    
                   NULL,
                   wszCmdLine,
                   NULL,            // ProcessAttributes
                   NULL,            // ThreadAttributes
                   FALSE,           // InheritHandles
                   CREATE_UNICODE_ENVIRONMENT,               // CreationFlags
                   pEnv,            // Environment
                   NULL,            // CurrentDirectory
                   &si,
                   &ProcInfo);      // ProcessInformation
               DestroyEnvironmentBlock(pEnv);
           }
           RevertToSelf();
       }
       UnloadUserProfile(m_hUserToken, sProfileInfo.hProfile);
   }

   if (bSuccess)
   {
       CloseHandle(ProcInfo.hThread);
       CloseHandle(ProcInfo.hProcess);
   }

   return bSuccess;
}

1 个答案:

答案 0 :(得分:3)

尝试在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),您将获得所有具有相同总面积的图表(假设所有子图以相同比例显示)。
  • 如果您现在需要“缩小”其中一个图表以便将其面积减少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将开始重新缩放子图,因此请检查结果(例如,通过ax.set_axis_on()在子图周围添加轴,并确保所有子图具有相同的宽度。)