Seaborn:线条图:一条线条有多种颜色

时间:2019-04-03 16:45:51

标签: plot colors line seaborn

出于各种原因,我正在从R迁移到python,并在此过程中切换了绘图系统。

在R中,我使用ggplot2绘制了显示折线图的图表,其中折线的颜色取决于要绘制的y值的范围。

除了绘制分段的线(每条线都有其自己的颜色)并将其缝合在一起之外,我一直找不到能够与R代码媲美的美观且苗条的解决方案。

R代码如下

ISP <- list(
    provider = list(
        name = "UPC",
        product = "Fiber Power Pack Medium",
        location = "Vienna",
        from = ymd_hms("2015-11-30 12:00:00"),
        to = ymd_hms("2017-06-14 18:00:00")
    ),
    download = list(
        speed = 75,
        min = 0,
        max = 100,
        colour = "seagreen",
        linetype = "dashed",
        fontsize = 3,
        from = ymd_hms("2015-11-30 12:00:00"),
        to = ymd_hms("2017-06-14 18:00:00")
    ),
    upload = list(
        speed = 7.5,
        min = 0,
        max = 10.0,
        colour = "seagreen",
        linetype = "dashed",
        fontsize = 3,
        from = ymd_hms("2015-11-30 12:00:00"),
        to = ymd_hms("2017-06-14 18:00:00")
    ),
    latency = list(
        speed = 1.0,
        min = 0,
        max = 1500.0,
        colour = "seagreen",
        linetype = "dashed",
        fontsize = 3,
        from = ymd_hms("2015-11-30 12:00:00"),
        to = ymd_hms("2017-06-14 18:00:00")
    )
) # ISP

LVL <- list(
    speed = list(
        lbl = c("non-acceptable", "bad", "poor", "mediocre", "good", "excellent"),
        lvl = c(-100, 0.5, 0.65, 0.80, 0.90, 0.99, 100),
        col = c("darkred", "red", "orange", "yellow", "yellowgreen", "green")
    ),
    latency = list(
        lbl = c("excellent", "good", "mediocre", "poor", "bad", "non-acceptable"),
        lvl = c(0.0, 2.0, 5.0, 25.0, 50.0, 200.0, 1000000.0),
        col = c("green", "yellowgreen", "yellow", "orange", "red", "darkred")
    ),
    time = list(
        lbl = c("night", "morning", "mid-morning", "midday", "afternoon", "evening", "night2"),
        lvl = c("00:00:00", "04:30:00", "09:30:00", "11:30:00", "14:00:00", "17:30:00", 
                "21:30:00", "23:59:59"),
        col = c("darkblue", "lightblue2", "skyblue2", "deepskyblue2", "deepskyblue3", 
                "deepskyblue4", "darkblue")
    )
) # LVL
names(LVL$speed$col) <- LVL$speed$lbl
names(LVL$latency$col) <- LVL$latency$lbl
names(LVL$time$col) <- LVL$time$lbl

LOG <- list(
    fnametst = file.path("../data/spdtst.log"),
    fname = file.path("/data/logfile/host/spdtst.log"),
    cnraw = c("Server ID", "Sponsor", "Server Name", "Timestamp", "Distance", 
              "Ping", "Download", "Upload"),
    clraw = c("factor", "factor", "factor", "POSIXct", "double", "double",
              "double", "double"),
    cnfin = c("Date", "Time", "Timestamp", "Week", "DoW", "ToD", 
              "Ping", "PCat", "Download", "DLCat", "Upload", "ULCat",
              "Server ID", "Sponsor", "Server Name", "Distance"),
    cntfin = c("Date", "Time", "Timestamp", "Week", "DoW", "ToD", 
               "ValueType", "Value", "Category",
               "Server ID", "Sponsor", "Server Name", "Distance")
) # LOG

pltTime <- function(dt=NULL, catcols=NULL, catcoll=NULL,
                       isrv=NULL, iloc=NULL, iprod=NULL) {

    gtcmn <- getMeanCol(dt)
    gtcdn <- gtcmn$download
    gtcup <- gtcmn$upload
    gtcpg <- gtcmn$latency

    gtdn <- ggplot(data=dt, aes(Timestamp, Download)) +
            geom_line(aes(colour=DLCat, group=1), show.legend=FALSE) +
            scale_colour_manual(values=catcols) +
            geom_hline(yintercept=ISP$download$speed, 
                       colour=ISP$download$colour, lty=ISP$download$linetype) +
            geom_smooth(method="lm", formula=y~x, aes(colour=NA), colour=gtcdn) +
            ylim(ISP$download$min, ISP$download$max) +
            labs(x="", y="Download Speed\n[mbit/s]") +
            annotate(geom="text", size=ISP$download$fontsize, hjust=0,
                     label=paste(isrv, "/", iprod, ": target download speed", sep=""),
                     x=min(dt$Timestamp), y=(ISP$download$speed + 5), 
                     color=ISP$download$colour)
    gtup <- ggplot(data=dt, aes(Timestamp, Upload)) +
            geom_line(aes(colour=ULCat, group=1), show.legend=FALSE) +
            scale_colour_manual(values=catcols) +
            geom_hline(yintercept=ISP$upload$speed, 
                       colour=ISP$upload$colour, lty=ISP$upload$fontsize) +
            geom_smooth(method="lm", formula=y~x, aes(colour=NA), colour=gtcup) +
            ylim(ISP$upload$min, ISP$upload$max) +
            labs(x="", y="Upload Speed\n[mbit/s]") +
            annotate(geom="text", size=ISP$upload$fontsize, hjust=0,
                     label=paste(isrv, "/", iprod, ": target upload speed", sep=""),
                     x=min(dt$Timestamp), y=(ISP$upload$speed + 0.5), 
                     color=ISP$upload$colour)
    gtpg <- ggplot(data=dt, aes(Timestamp, Ping)) +
            geom_line(aes(colour=PCat, group=1), show.legend=FALSE) +
            scale_colour_manual(values=catcoll) +
            geom_hline(yintercept=ISP$latency$speed, 
                       colour=ISP$latency$colour, lty=ISP$latency$linetype) +
            geom_smooth(method="lm", formula=y~x, aes(colour=NA), colour=gtcpg) +
            ylim(ISP$latency$min - 70, ISP$latency$max) +
            labs(x="", y="Latency\n[ms]") +
            annotate(geom="text", size=ISP$latency$fontsize, hjust=0,
                     label=paste(isrv, "/", iprod, ": target latency", sep=""),
                     x=min(dt$Timestamp), y=(ISP$latency$speed - 60), 
                     color=ISP$latency$colour)

    gmt <- textGrob("Internet Speed Monitoring", gp=gpar(fontsize=20))
    gst <- textGrob(paste("(", isrv, " / ", iloc, " / ", iprod, ")", sep=""), 
                    gp=gpar(fontsize=12))
    margin <- unit(0.5, "line")
    glgd <- legendGrob(LVL$speed$lbl, nrow=1, do.lines=TRUE,
                       gp=gpar(col=LVL$speed$col, fontsize=10))

    # arrange chart elements & display plot
    grid.arrange(gmt, gst, gtdn, gtup, gtpg, glgd, nrow=6, ncol=1,
                 heights=unit.c(grobHeight(gmt) + 1.2 * margin, 
                                grobHeight(gst) + margin, 
                                unit(1, "null"), unit(1, "null"), unit(1, "null"),
                                grobHeight(glgd) + margin))

} # pltTime

可绘制类似

的图

enter image description here

我相应的python代码,简化了matplotlib的样子

def pltTimeMatplotlib(df=None, catcols=None, catcoll=None, isrv=None,     iloc=None, iprod=None,
                      showfit=True, figsize='MEDIUM', backend='Agg', showfig=cmn.IsInteractive()):
    gtcmn = lgmnc.getMeanCol(df)
    gtcdn = gtcmn['download']
    gtcup = gtcmn['upload']
    gtcpg = gtcmn['ping']
    gtit = lgd.INFO['Title']
    gstit = lgd.INFO['Subtit'] % (isrv, iloc, iprod)

    # set up plotting environment
    cmn.SetPlotBackendMatplotlib(backend)
    cmn.SetPlotPropertiesMatplotlib()

    # new plot (3 rows, 1 column)
    fig, ax = plt.subplots(nrows=3, ncols=1, sharex=True, figsize=cmn.GetFigSize(figsize)['SIZE'])

    # plot download values
    # ax[0].set_title(gtit + '\n' + '$\\regular_{{' + gstit + '}}$', fontsize=20)
    lpcl.ColLineMatplotlib(ax, row=0, x=df.Timestamp, y=df.Download, w=df.DLCat,
                           name=lgd.INFO['Dnld']['Name'], lbls=lgd.ISP_SPD_LVL['lbl'],
                           style='solid', colors=lgd.ISP_SPD_LVL['col'],
                           alpha=lgd.INFO['FitVal']['AlphaObs'] if showfit else 1,
                               ytitle=lgd.INFO['Dnld']['Yaxis'], ymin=lgd.ISP['DlSpdMin'], ymax=lgd.ISP['DlSpdMax'])
    lphl.HorLineMatplotlib(ax, row=0, x=df.Timestamp, y=lgd.ISP['DlSpd'],
                           name='%s / %s: target download speed' % (isrv, iprod), fs=lgd.ISP['DlSpdFsz'],
                           color=lgd.ISP['DlSpdCol'], style=lgd.ISP['DlSpdLty'])

    if showfit:
        lpfl.pltFitLineMatplotlib(ax, row=0, x=df.Timestamp, y=df.DLFit, se=df.DLFit_se95, color=gtcmn['download'])

    # plot upload values
    lpcl.ColLineMatplotlib(ax, row=1, x=df.Timestamp, y=df.Upload, w=df.ULCat,
                           name=lgd.INFO['Upld']['Name'], lbls=lgd.ISP_SPD_LVL['lbl'],
                           style='solid', colors=lgd.ISP_SPD_LVL['col'],
                           alpha=lgd.INFO['FitVal']['AlphaObs'] if showfit else 1,
                           ytitle=lgd.INFO['Upld']['Yaxis'], ymin=lgd.ISP['UlSpdMin'], ymax=lgd.ISP['UlSpdMax'])
    lphl.HorLineMatplotlib(ax, row=1, x=df.Timestamp, y=lgd.ISP['UlSpd'],
                           name='%s / %s: target upload speed' % (isrv, iprod), fs=lgd.ISP['UlSpdFsz'],
                           color=lgd.ISP['UlSpdCol'], style=lgd.ISP['UlSpdLty'])

    if showfit:
        lpfl.pltFitLineMatplotlib(ax, row=1, x=df.Timestamp, y=df.ULFit, se=df.ULFit_se95, color=gtcmn['upload'])

    # plot latency values
    lpcl.ColLineMatplotlib(ax, row=2, x=df.Timestamp, y=df.Ping, w=df.PCat,
                           name=lgd.INFO['Lat']['Name'], lbls=lgd.ISP_SPD_LVL['lbl'],
                           style='solid', colors=lgd.ISP_SPD_LVL['col'],
                           alpha=lgd.INFO['FitVal']['AlphaObs'] if showfit else 1,
                           ytitle=lgd.INFO['Lat']['Yaxis'], ymin=lgd.ISP['PgSpdMin'], ymax=lgd.ISP['PgSpdMax'])
    lphl.HorLineMatplotlib(ax, row=2, x=df.Timestamp, y=lgd.ISP['PgSpd'],
                           name='%s / %s: target upload speed' % (isrv, iprod), fs=lgd.ISP['PgSpdFsz'],
                           color=lgd.ISP['PgSpdCol'], style=lgd.ISP['PgSpdLty'])

    if showfit:
        lpfl.pltFitLineMatplotlib(ax, row=2, x=df.Timestamp, y=df.PFit, se=df.PFit_se95, color=gtcmn['ping'])

    # add legend
    ax[0].legend(handles=[Patch(facecolor=lgd.ISP_SPD_LVL['col'][i], edgecolor=lgd.ISP_SPD_LVL['col'][i],
                                label=lgd.ISP_SPD_LVL['lbl'][i]) for i in
                          range(0, len(lgd.ISP_SPD_LVL['lbl']))],
                 bbox_to_anchor=(1.02, 1), loc='upper left')

    # show plot
    fig.tight_layout()
    if showfig:
        fig.show()

    return fig

# pltTimeMatplotlib

其结果如下图所示

enter image description here

不像R生成的图:(

将seaborn放置到位

fig, ax = plt.subplots(nrows=3, ncols=1, sharex=False, figsize=(11, 8))
sns.relplot(data=df, x='Timestamp', y='Download', hue='DLCat', kind='line', ax=ax[0])
sns.relplot(data=df, x='Timestamp', y='Upload', hue='ULCat', kind='line', ax=ax[1])
sns.relplot(data=df, x='Timestamp', y='Ping', hue='PCat', kind='line', ax=ax[2])

生成的图表看起来像

enter image description here

虽然更好,但与R的功能还差得很远! :(

尝试使用ggplot或plotnine for python也是没有用的!

问题是,如何完成当前的任务,根据y值的值范围将数据绘制成一条具有多种颜色的单行?

样本数据如下

  

Date; Time; Timestamp; TimestampNumeric; Week; DoW; ToD; Ping; PCat; PFit; PFit_se95; Download; DLCat; DLFit; DLFit_se95; Upload; ULCat; ULFit; ULFit_se95; Ppred; DLpred; ULpred; Server   ID;赞助商;服务器名称;距离2017-01-21; 17:00:31.428487; 2017-01-21   17:00:31.428487 + 00:00; 1485018031428487000; 3; 5;下午; 27.816;可怜; 61.0515; 0.355177064584112; 25.618352217411623;不可接受; 41.44800971735411; 0.2411305606621227; 4.568323448491203;坏; 4.191237824977095; 21143832100382343856 5351; UPC;维也纳; 3.19765478758952   2017-01-21; 18:00:10.586704; 2017-01-21   18:00:10.586704 + 00:00; 1485021610586704000; 3; 5;晚上; 380.293;不可接受; 61.0515; 0.355177064584112; 37.7609753962603;坏; 41.44800971735411; 0.2411305606621227; 3.6552732012186175;不可接受; 4.191237824977095; 0.0243832100382370972 4.065124709557566; 5351; UPC;维也纳; 3.19765478758952   2017-01-21; 19:00:08.426152; 2017-01-21   19:00:08.426152 + 00:00; 148502520842615615; 3; 5;晚上; 18.827;中庸; 61.0515; 0.355177064584112; 41.25280065801174; bad; 41.44800971735411; 0.2411305606621227; 4.048148873503645; bad; 4.191237824977095; 0.024383210038234328; 723453652; 8725352829 UPC;维也纳; 3.19765478758952   2017-01-21; 20:00:08.652402; 2017-01-21   20:00:08.652402 + 00:00; 1485028808652402000; 3; 5; evening; 63.001999999999995; bad; 61.0515; 0.355177064584112; 53.61886006608488488; poor; 41.44800971735411; 0.2411305606621227; 4.729607515909154; bad; 4.191237824977095; 0.0243832100382343988; 444 UPC;维也纳; 3.19765478758952   2017-01-21; 20:50:08.450669; 2017-01-21   20:50:08.450669 + 00:00; 1485031808450669000; 3; 5;晚上; 19.615;中等; 61.0515; 0.355177064584112; 25.665746080621417;不可接受; 41.44800971735411; 0.2411305606621227; 4.796502111349239;坏; 4.191237824977095; 0.0243832100382343564 5351; UPC;维也纳; 3.19765478758952   2017-01-21; 20:55:07.826120; 2017-01-21   20:55:07.826120 + 00:00; 1485032107826120000; 3; 5; evening; 19.848; mediocre; 61.0515; 0.355177064584112; 30.69814989932061;不可接受; 41.44800971735411; 0.2411305606621227; 3.911586957043801; bad; 4.191237824977095; 0.024381.6100382483483 5351; UPC;维也纳; 3.19765478758952   2017-01-21; 21:00:08.710337; 2017-01-21   21:00:08.710337 + 00:00; 1485032408710337000; 3; 5;晚上; 24.234;中庸; 61.0515; 0.355177064584112; 36.243021683794225;不可接受; 41.44800971735411; 0.2411305606621227; 4.0998941629635235;坏; 4.191237824977095; 0.024381.6100542591685542 5351; UPC;维也纳; 3.19765478758952   2017-01-21; 21:05:07.854203; 2017-01-21   21:05:07.854203 + 00:00; 1485032707854203000; 3; 5; evening; 18.512999999999998; mediocre; 61.0515; 0.355177064584112; 63.89399013998417; mediocre; 41.44800971735411; 0.2411305606621227; 4.708668774848805; bad; 4.191237824977095; 0.0243832100535 UPC;维也纳; 3.19765478758952   2017-01-21; 21:10:08.013815; 2017-01-21   21:10:08.013815 + 00:00; 1485033008013815000; 3; 5; evening; 19.685; mediocre; 61.0515; 0.355177064584112; 51.11533006159361; poor; 41.44800971735411; 0.2411305606621227; 3.894617295197565; bad; 4.191237824977095; 0.0243832100382343152; 784725597832578783; 825.79572559 UPC;维也纳; 3.19765478758952   2017-01-21; 21:15:08.770008; 2017-01-21   21:15:08.770008 + 00:00; 1485033308770008000; 3; 5; evening; 18.682000000000002; mediocre; 61.0515; 0.355177064584112; 48.61287097045852; bad; 41.44800971735411; 0.2411305606621227; 3.499755909245393; non-acceptable; 4.191237824977343; 61221372542571 5351; UPC;维也纳; 3.19765478758952   2017-01-21; 21:20:08.335233; 2017-01-21   21:20:08.335233 + 00:00; 1485033608335233000; 3; 5; evening; 28.765; poor; 61.146398668079925; 0.3557291530727089; 57.78429519204259; poor; 44.59951058428095; 0.25946493126643805; 3.617760293577565; non-acceptable; 4.013007169522658; 657.671552 5351; UPC;维也纳; 3.19765478758952   2017-01-21; 21:25:07.595897; 2017-01-21   21:25:07.595897 + 00:00; 1485033907595897000; 3; 5; evening; 17.808; mediocre; 24.897899953382083; 0.14484759620568127; 40.58008130117975; bad; 44.95005528438813; 0.2615042822666524; 4.846561592491617; bad; 4.399405074720; 67810345 UPC;维也纳; 3.19765478758952   2017-01-21; 21:30:06.696604; 2017-01-21   21:30:06.696604 + 00:00; 1485034206696604000; 3; 5; night; 21.912;中庸; 25.20639984297373; 0.14664234465919482; 55.758053601793186;可怜; 46.40664856554451; 0.26997825138934495; 3.9817180828677077;坏; 4.296760163388223; 211.17937159; 4691499371659498586 UPC;维也纳; 3.19765478758952   2017-01-21; 21:35:07.621935; 2017-01-21   21:35:07.621935 + 00:00; 1485034507621935000; 3; 5; night; 19.746; mediocre; 20.880800010908814; 0.12147746171744327; 64.46928022947392; mediocre; 47.555966522290774; 0.27666459616631106; 4.367025026005708; bad; 3.7017214839869; 29.10721476976376.7637 UPC;维也纳; 3.19765478758952   2017-01-21; 21:40:06.708005; 2017-01-21   21:40:06.708005 + 00:00; 1485034806708005000; 3; 5; night; 17.195; mediocre; 20.638800020061893; 0.12006958727736576; 42.34943908253596; bad; 49.25391971331539; 0.2865427159535292; 3.659186074866285; non-acceptable; 3.5666574383690160; 211.6154.0695211 96819695832 5351; UPC;维也纳; 3.19765478758952   2017-01-21; 21:45:07.585452; 2017-01-21   21:45:07.585452 + 00:00; 1485035107585452000; 3; 5; night; 72.68;坏; 25.92199981133212; 0.1508054642578618; 33.264833182498464;不可接受; 49.51729031610259; 0.2880749174161584; 4.680825273248062;坏; 4.227379607990; 65.280.678.678.678.678 5351; UPC;维也纳; 3.19765478758952   2017-01-21; 21:50:07.047709; 2017-01-21   21:50:07.047709 + 00:00; 1485035407047709000; 3; 5; night; 18.486; mediocre; 25.347199958958193; 0.14746147231188908; 55.29159625271184; poor; 51.28928106388433; 0.29838376277241213; 4.325532270698096; bad; 4.410035724194347; 0.021656547654743 UPC;维也纳; 3.19765478758952   2017-01-21; 21:55:07.044989; 2017-01-21   21:55:07.044989 + 00:00; 1485035707044989000; 3; 5; night; 25.735;较差; 26.069400016204455; 0.1516629890047665; 69.12248336419916; good; 51.77297774514084; 0.3011977471527757; 3.2228828374942005; non-acceptable; 4.175135307718962; 6.473654654.265 5351; UPC;维也纳; 3.19765478758952   2017-01-21; 22:00:08.194176; 2017-01-21   22:00:08.194176 + 00:00; 1485036008194176000; 3; 5; night; 21.064; mediocre; 26.207300074355146; 0.1524652450977362; 60.42381825543723; mediocre; 52.6974264844093; 0.3065758785594054; 3.628847526533604; non-acceptable; 4.016201640917695; 405.345695695679 5351; UPC;维也纳; 3.19765478758952   2017-01-21; 22:05:06.926742; 2017-01-21   22:05:06.926742 + 00:00; 1485036306926742000; 3; 5; night; 20.938000000000002; mediocre; 26.43290009012283; 0.15377771000638701; 55.146925342278784; poor; 53.36483355320812; 0.31045862810001706; 3.521208779670928; non-acceptable; 4.17172016388489669697692692617692617 5351; UPC;维也纳; 3.19765478758952   2017-01-21; 22:10:07.959275; 2017-01-21   22:10:07.959275 + 00:00; 1485036607959275000; 3; 5; night; 18.429000000000002; mediocre; 25.399300142795635; 0.1477645736338824; 46.03641783482493; bad; 52.28476902058916; 0.30417517641976327; 3.4654039347434558; non-acceptable; 4.492844314391669650; 613785748; 613785654;​​ 675328; 654328 5351; UPC;维也纳; 3.19765478758952   2017-01-21; 22:15:08.230382; 2017-01-21   22:15:08.230382 + 00:00; 1485036908230382000; 3; 5; night; 17.505; mediocre; 25.369000113299577; 0.14758829826745865; 66.96316097320238; mediocre; 54.836440881937804; 0.3190199438946933; 3.5767577697812523; non-acceptable; 3.7779106558622669670920; 69157 678570 6886.7914; 675.678.678.678 5351; UPC;维也纳; 3.19765478758952   2017-01-21; 22:20:08.146512; 2017-01-21   22:20:08.146512 + 00:00; 1485037208146512000; 3; 5; night; 264.835; non-acceptable; 49.661299147268366; 0.2889127122930681; 63.13266165897449; mediocre; 55.58929181324165; 0.3233997770494874; 3.6391479124686814; non-acceptable; 3.430706197846698842596; 4.065167406596675; 5351; UPC;维也纳; 3.19765478758952   2017-01-21; 22:25:07.502934; 2017-01-21   22:25:07.502934 + 00:00; 1485037507502934000; 3; 5; night; 17.43; mediocre; 49.42969966251185; 0.28756534449448795; 65.1974496994903; mediocre; 55.746088411282095; 0.3243119668470973; 3.6258034857463564; non-acceptable; 3.5727821456185933; 671265 5351; UPC; Vienna; 3.19765478758952

0 个答案:

没有答案