可视化SLA性能

时间:2018-07-12 02:55:18

标签: r latex r-markdown

我每个月都会为我们的高级领导撰写一份报告-它显示了I.T.性能。诸如事件解决,系统可用性等方面的信息。我一直在寻找方法来可视化我拥有的一些数据,并找到了漂亮的表示形式,如下所示:

enter image description here

我喜欢这种布局。我所有的报告都在RMarkdown中与一些混合LaTex一起使用。我一直在考虑如何在Rmarkdown中复制这样的内容,或者甚至只是使用嵌入在我的markdown文件中的原始LaTex ...我已经知道我可以使用sparklines包来获取sparklines,可以从中获取值和标题数据。我唯一的旅行就是整个事情。

我可以在ggplot中做类似的事情吗?或者也许使用晶格...我迷失了如何将所有这些放在一起。

一些基本信息-我的数据集是R数据框。每行包含一个不同的系统或指标。将有一系列包含效果的列(计数和百分比)。我设想了某种循环,它将构建每个框,然后以某种方式将其全部放入网格中。

如果需要,我可以提供样本数据集,但是它们是非常基本的。字段/列类似于:名称,目标,2018年1月,2018年2月等。如果某些指标同时需要计数和百分比,则可能每个月都有包含计数和百分比的列。

关于如何重现此事的任何想法?

样本数据

这是示例数据集。我希望迷你图成为百分比,但我也有每月的工作时间。显示的数字可以是年初至今的小时数和年初至今的百分比。抱歉,对于较晚的数据集-我必须进行清理才能删除机密信息。我已经添加了CSV和RData格式。再次感谢!

Data CSV File

Data RData File

2 个答案:

答案 0 :(得分:2)

这个问题有很多部分,我同意这样的意见,即确切的解决方案将取决于许多细节。但是,假设您正在寻找一种可以创建某种形式的静态仪表板的解决方案,则可以使用经过大量编辑的ggplot构建与此类似的内容。

我已经编写了一个函数metricplot,可以轻松创建许多此类较小的图表。它具有以下变量:

  • df :包含数据的数据框
  • x y :用于x和y轴的列
  • 标题:剧情的标题
  • 颜色:小部件的颜色

功能如下:

#' Make a small metric plot
#' 
#' 
metricplot <- function(df, x, y, title, colour){

  # Find the change in values
  start <- df[[y]][1]
  end <- df[[y]][length(df)]
  change <- scales::percent((end - start)/start)


  plot <- 
    ggplot(df) +
    annotate("rect", xmin = -Inf, xmax = Inf, ymax = max(df[[y]] - 1), 
             ymin = min(df[[y]]), fill = "white", alpha = 0.5) +
    geom_line(aes_string(x, y), colour = "white", size = 2) +
    labs(title = title,
         subtitle = paste0(end, " / ", change)) +
    theme(axis.line=element_blank(),
          axis.text.x=element_blank(),
          axis.text.y=element_blank(),
          axis.ticks=element_blank(),
          axis.title.x=element_blank(),
          axis.title.y=element_blank(),legend.position="none",
          panel.background=element_blank(),
          panel.border=element_blank(),
          panel.grid.major=element_blank(),
          panel.grid.minor=element_blank(),
          plot.background = element_rect(fill = colour),
          plot.title = element_text(size = 20, colour = "white", face = "plain"),
          plot.subtitle = element_text(size = 40, colour = "white", face = "bold")) 

  return(plot)

}

将此功能与示例数据集结合使用:

 set.seed(123)
df2 <- data.frame(x = 1:20,
                  y = c(9, rep(10, 17), 12, 14),
                  z = c(14, rep(10, 17), 12, 11))

library(ggplot2)
library(ggthemes)

grid.arrange(metricplot(df2, "x", "y", "Metric 1", "#fc8d59"),
             metricplot(df2, "x", "y", "Metric 1", "#91cf60"),
             metricplot(df2, "x", "z", "Something Else", "#999999"),
             metricplot(df2, "x", "z", "One More", "#fc8d59"), ncol=4)

enter image description here

很明显,这已经对数据的格式做了一些假设,但希望它可以使您朝着正确的方向前进:)

答案 1 :(得分:1)

我已经从下面的示例代码重写了@ mikey-harper的答案中的第一部分代码。这修改了他的代码以使用我的数据集格式。仍然需要进行一些调整才能获得我想要的格式,但就目前而言,这是一个良好的开端。只是想发布我的进度。

# Needed Libraries

library(Hmisc)
library(zoo)
library(lubridate)
library(ggplot2)
library(ggthemes)
library(grid)
library(gridExtra)

# Plot Function

metricplot <- function(data = criticalSystemAvailabilityFullDetail, row = 1) {

  # Since data is organized by row, I need to pull only the columns I need 
  # for the particular row (system) specificied. Then turn it into columns
  # since ggplot works best this way.
  ytdMonths <- as.data.frame(names(data)[4:((month(Sys.Date())-1)+3)])
  ytdValue <- t(as.data.frame(data[row,((month(Sys.Date()))+3):(ncol(data)-2)][1,]))
  ytdData <- cbind(ytdMonths, ytdValue)
  names(ytdData)[1] <- "Month"
  names(ytdData)[2] <- "Value"

  # Since I need red, yellow and green for my thresholds, I already have my 
  # target. My rules for this are basically, green until it exceeds 50%
  # of the target, then it turns yellow. Once it exceeds the Target, it turns
  # red. This function is called when the plot is made to determine the background
  # color.
  colour <- function (system = data[row,]) {
    if(data[row,ncol(data)] < as.numeric(strsplit(data[row,2], "%")[[1]][1]) ) {
      return("#fc5e58")
    } else if((data[row,ncol(data)] > as.numeric(strsplit(data[row,2], "%")[[1]][1])) == TRUE & (data[row,ncol(data)] < ((as.numeric(strsplit(data[row,2], "%")[[1]][1]) + 100.00) / 2)) == TRUE) {
      return("#ebc944")
    } else {
      return("#8BC34A")
    }
  }

  # Now for the plot. I have made some slight modifications to this. For example, in the white area that 
  # represents the high and low - I have used 100% for the max and the target for the low. I do this dynamically
  # by using the target from the row (system) I am currently plotting. I adjusted the line size down to 1, since 
  # the preivous value made the line a little too big. 
  plot <- 
    ggplot(ytdData) +
    annotate("rect", xmin = -Inf, xmax = Inf, ymax = 100.000, ymin = as.numeric(strsplit(data[row,2], "%")[[1]][1]), fill = "white", alpha = 0.6) + # Create the plot
    geom_line(aes(x = as.yearmon(Month), y = Value), colour = "white", size = 1) +
    labs(title = data[row,1], subtitle = paste0(data[row,ncol(data)], "% / ", data[row,(ncol(data)-1)], " hours")) + # Add title and subtitle
    theme(axis.line=element_blank(), # Remove X-axis title
          axis.text.x=element_blank(), # Remove X-Xais Text
          axis.text.y=element_blank(), # Remove Y-Axis Text - Comment this whole line out if you want a scale on the y-axis.
          axis.ticks=element_blank(), # Remove X-Axis
          axis.title.x=element_blank(), # Remove X-Axis Titlke
          axis.title.y=element_blank(),legend.position="none", # Remove legend and Y-axis title
          panel.background=element_blank(), # Remove bland gray background
          panel.border=element_blank(), # Remove border
          panel.grid.major=element_blank(), # Remove Grid
          panel.grid.minor=element_blank(), # Remove Grid
          plot.background = element_rect(fill = colour()), # Red, Green, Yellow
          plot.title = element_text(size = 10, colour = "white", face = "plain"), # Main Title
          plot.subtitle = element_text(size = 15, colour = "white", face = "bold"))

  return(plot) # Return the plot.
}



# Now we build the the grid by calling each row. Depending on the size of the canvas, 
# you might want to break up how many rows on the grid you do. In my case, this 
# is going on an A4 size peice of paper, so I will probably limit it to about 5-6 rows 
# in order to provide a readable page. Squeezing 5 columns in could get you more
# on a page, too. 

grid.arrange(metricplot2(data = criticalSystemAvailabilityFullDetail, row=1),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=2),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=3),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=4),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=5),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=5),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=7),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=8),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=9),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=10),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=11),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=12),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=13),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=14),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=15),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=16),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=17),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=18),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=19),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=20),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=21),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=22),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=23),
             metricplot2(data = criticalSystemAvailabilityFullDetail, row=24), ncol=4)

我唯一想念的是如何减少小时数(字幕的第二部分)。我不知道我是否可以使用第3个字幕,但需要尝试一下。否则,我需要弄清楚如何在字幕中使用不同的大小。否则,这似乎可以正常工作。

enter image description here