出于各种原因,我正在从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
可绘制类似
的图我相应的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
其结果如下图所示
不像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])
生成的图表看起来像
虽然更好,但与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