如何制作映射事件持续时间和事件数量的自定义图表?

How to make custom graph that maps duration of events and amount of events?

我有一个显示血细胞之间随时间发生的接触事件的数据集。我有关于事件从哪一帧开始以及何时结束的数据。数据框如下所示:

Cell_id1 Cell_id2 Begin_frame End_frame
ID_1 ID_10 4 5
ID_1 ID_10 12 18
ID_1 ID_11 16 20
ID_1 ID_12 22 24

我想要制作的图表如下所示:

带线的绿点代表Cell_id1,带线的红点代表Cell_id2中的单元格。 X 轴代表帧,因此每个点都是一个新帧。每次与不同的单元格发生接触事件时,它都会在 y 轴上向上移动 1。

绿点后面的红圈可以忽略。

我不知道该怎么做,所以即使是正确方向的提示也很棒!

第一步是计算出 Y 轴上的位置。

计算第二列中 不同 id 的数量(在您的示例中有 3 个)按照第一次联系的顺序将每个 id 分配给一个整数。在您的示例中,您将得到

contacted cell position on Y-axis
ID10 1
ID11 2
ID12 3

这是绘制图形的伪代码。请注意,它在联系人的结束帧处放置了一个点。

LOOP over contacted cells
   SET contact false
   LOOP over frames
      IF begin frame
         SET contact true
      IF contact true
          X = time frame number
          Y = position on Y from above table
          Draw red dot at X,Y
      IF end frame
          SET contact false

这是该算法的 C++ 实现。

第一步:为接触到的每个调用对分配唯一索引

void cContacts::indexContacts()
{
    for (auto &contact : myContact)
    {
        if (std::find(
                myUnique.begin(),
                myUnique.end(),
                contact) == myUnique.end())
            myUnique.push_back(contact);
    }
}

第 2 步:使用上述伪代码算法绘制点

void cContacts::placeDots()
{
    // loop over contacts
    for (auto &contact : myContact)
    {
        // track whether we are in contact
        bool incontact = false;

        // loop over frames
        for (int frame = 1; frame <= mymaxframe; frame++)
        {
            if (frame == contact.start)
                incontact = true;

            if (incontact)
            {
                // in contact - work out y position of dot from unique index
                int yPosition = std::find(
                                    myUnique.begin(),
                                    myUnique.end(),
                                    contact) -
                                myUnique.begin() + 1;

                // draw the dot - here I just output the co=-ordinates
                std::cout << "dot at " << frame << "," << yPosition << "\n";
            }

            if (frame == contact.end)
                incontact = false;
        }
    }
}

输出看起来像这样

dot at 4,0
dot at 5,0
dot at 12,0
dot at 13,0
dot at 14,0
dot at 15,0
dot at 16,0
dot at 17,0
dot at 18,0
dot at 16,1
dot at 17,1
dot at 18,1
dot at 19,1
dot at 20,1
dot at 22,2
dot at 23,2
dot at 24,2

使用这些位置绘制红色圆圈

您可以在 https://github.com/JamesBremner/bloodcell2

找到此应用程序的完整代码