在matplotlib/gnuplot中绘制带标签的间隔

在matplotlib/gnuplot中绘制带标签的间隔,plot,matplotlib,gnuplot,intervals,Plot,Matplotlib,Gnuplot,Intervals,我有一个数据示例,如下所示: a 10:15:22 10:15:30 OK b 10:15:23 10:15:28 OK c 10:16:00 10:17:10 FAILED b 10:16:30 10:16:50 OK 我想用以下方式绘制上述数据: captions ^ | c | *------* b | *---* *--* a | *--* |___________________ time > 线的颜

我有一个数据示例,如下所示:

a 10:15:22 10:15:30 OK
b 10:15:23 10:15:28 OK
c 10:16:00 10:17:10 FAILED
b 10:16:30 10:16:50 OK
我想用以下方式绘制上述数据:

captions ^
  |
c |         *------*
b |   *---*    *--*
a | *--*
  |___________________
                     time >
线的颜色取决于数据点的
OK/FAILED
状态。标签(
a/b/c/…
)可以重复,也可以不重复

正如我从gnuplotmatplotlib的文档中收集到的,这种类型的绘图应该更容易在后者中进行,因为它不是标准绘图,需要一些预处理

问题是:

  • 在任何工具中都有这样绘制的标准方法吗
  • 如果没有,我应该如何绘制这些数据(指向相关工具/文档/函数/示例的指针,这些工具/文档/函数/示例执行类似于此处描述的操作)

  • 更新:现在包括处理数据样本和使用mpl日期功能

    导入matplotlib.pyplot作为plt
    从matplotlib.dates导入日期格式化程序、MinuteLocator、SecondLocator
    将numpy作为np导入
    从StringIO导入StringIO
    将日期时间导入为dt
    ###示例数据
    a=StringIO(““”a 10:15:22 10:15:30好的
    b 10:15:23 10:15:28好的
    c 10:16:00 10:17:10失败
    b 10:16:30 10:16:50好的
    """)
    #将str转换为datetime对象。
    conv=lambda s:dt.datetime.strtime(s,“%H:%M:%s”)
    #使用numpy读取中的数据。
    data=np.genfromtxt(a,converters={1:conv,2:conv},
    名称=[“标题”、“开始”、“停止”、“状态”],数据类型=无)
    cap,start,stop=数据['caption'],数据['start'],数据['stop']
    #检查状态,因为我们用相同的颜色绘制所有线条
    #一起
    是否正常=(数据['state']=“正常”)
    不正常=np。逻辑不正常(正常)
    #获取唯一的标题、索引和反向映射
    标题,唯一的\u idx,标题\u inv=np.unique(cap,1,1)
    #根据唯一标题的数量生成y值。
    y=(标题+1)/浮动(长(标题)+1)
    #绘图函数
    定义时间线(y、xstart、xstop、color='b'):
    “”“在y处用给定颜色绘制从xstart到xstop的时间线。”“”
    plt.hlines(y,xstart,xstop,color,lw=4)
    plt.vlines(xstart,y+0.03,y-0.03,彩色,lw=2)
    plt.V线(xstop,y+0.03,y-0.03,彩色,lw=2)
    #绘图ok tl黑色
    时间线(y[正常]、开始[正常]、停止[正常]、'k')
    #绘图失败tl红色
    时间线(y[不确定]、开始[不确定]、停止[不确定]、'r')
    #设置绘图
    ax=plt.gca()
    ax.xaxis_日期()
    myFmt=DateFormatter(“%H:%M:%S”)
    ax.xaxis.set\u major\u格式化程序(myFmt)
    ax.xaxis.set_major_locator(SecondLocator(interval=20))#用作SecondLocator(0,interval=20)
    #要调整xlimits,需要时间增量。
    增量=(stop.max()-start.min())/10
    plt.yticks(y[唯一的idx],标题)
    plt.ylim(0,1)
    plt.xlim(start.min()-delta,stop.max()+delta)
    plt.xlabel(“时间”)
    plt.show()
    

    gnuplot
    带向量的解决方案

    最小化自:

    main.gnuplot

    #!/usr/bin/env gnuplot
    
    $DATA << EOD
    1 1 5
    1 11 13
    2 3 10
    3 4 8
    4 7 13
    5 6 15
    EOD
    
    set terminal png size 512,512
    set output "main.png"
    set xrange [-1:]
    set yrange [0:]
    unset key
    set border 3
    set xtics nomirror
    set ytics nomirror
    set style arrow 1 nohead linewidth 3
    plot $DATA using 2 : 1 : ($3-$2) : (0.0) with vector as 1, \
         $DATA using 2 : 1 : 1 with labels right offset -2
    
    #/usr/bin/env gnuplot
    
    $DATAgnuplot 5.2版本,创建唯一的键列表

    @CiroSantilli解决方案的主要区别在于,从第1列自动创建唯一键列表,并且可以通过定义的函数
    Lookup()
    访问索引。引用的gnuplot演示已经使用了一个唯一项的列表,但是,在OP的例子中有重复项

    在gnuplot中不存在立即创建这样一个独特项列表的情况,因此您必须自己实现它。 该代码要求gnuplot>=5.2。可能很难找到一个在gnuplot 4.4(OP提出问题的时候)下工作的解决方案,因为当时没有实现一些有用的功能:
    do for
    -循环、
    求和、
    数据块。。。(gnuplot 4.6版本可能有一些解决方法)

    编辑:早期版本使用带有向量的
    线宽20
    来绘制条形图,但是,
    线宽20
    也在x方向延伸,这在这里是不需要的。因此,现在使用带有boxyError的

    代码:

    ### Time chart
    reset session
    
    $Data <<EOD
    # category        start    end      status
    "event 1"         10:15:22 10:15:30 OK
    "event 2"         10:15:23 10:15:28 OK
    pause             10:16:00 10:17:10 FAILED
    "something else"  10:16:30 10:17:50 OK
    unknown           10:17:30 10:18:50 OK
    "event 3"         10:18:30 10:19:50 FAILED
    pause             10:19:30 10:20:50 OK
    "event 1"         10:17:30 10:19:20 FAILED
    EOD
    
    # create list of keys
    List = ''
    set table $Dummy
        plot $Data u (List=List.'"'.strcol(1).'" ',NaN) w table
    unset table
    
    # create list of unique keys
    UniqueList = ''
    do for [i=1:words(List)] {
        item = word(List,i)
        found = 0
        do for [j=1:words(UniqueList)] {
            if (item eq word(UniqueList,j)) { found=1; break }
        }
        if (!found) { UniqueList = UniqueList.'"'.item.'" '}
    }
    print UniqueList
    
    # define functions for lookup and color
    Lookup(s) = (Index = NaN, sum [i=1:words(UniqueList)] \
        (Index = s eq word(UniqueList,i) ? i : Index,0), Index)
    Color(s) = s eq "OK" ? 0x00cc00 : 0xff0000
    
    set xdata time
    set timefmt  "%H:%M:%S"
    set format x "%M'".'%S"'
    set yrange [0.5:words(UniqueList)+0.5]
    plot $Data u (timecolumn(2)):(Idx=Lookup(strcol(1))): \
        (timecolumn(3)):(timecolumn(2)):(Idx-0.3):(Idx+0.3): \
        (Color(strcol(4))):ytic(strcol(1)) \
        w boxxyerror fill solid 1.0 lc rgb var notitle
    ### end of code
    
    时间图表 重置会话
    $Data谢谢。我已成功地以您的解决方案为基础绘制了一张图表。如果没有人提出更好的解决方案,我将接受您的答案。我更新了我的答案,我一直想学习matplotlibs日期功能。对于不同的结束符号,您将用分散符号替换V线。plt.scatter(xstart,y,s=100,c=color,marker='x',lw=2,edgecolor=color)此示例不适用于matplotlib 1.2(python 2.7,Fedora 19)-代码似乎卡在无限循环中。适用于Mac OS 10.10上的matplotlib 1.4.0 python 2.7。