如何使用 R dygraphs 创建条形图和折线图?

r_a*_*anb 5 r dygraphs

我想使用 dygraphs 创建条形图和折线图,这似乎应该可以基于此处的“条形图和折线图”dygraphs 示例以及dygraphs 包中提供的dyBarChart() 自定义绘图仪

使用自定义包装器,我可以创建一个条形图,因此我认为该代码正在运行:

library(dygraphs)

dyBarChart <- function(dygraph) {
  dyPlotter(
    dygraph = dygraph,
    name = "BarChart",
    path = system.file("examples/plotters/barchart.js",package = "dygraphs")
  )
}

lungDeaths <- cbind(ldeaths, mdeaths)
dygraph(lungDeaths) %>% 
  dyBarChart()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

我假设我可以用dySeries()来自定义我想用线/条显示的系列,但以下都不起作用。它们不会出错,但不会创建任何内容。我也不确定这是否"linePlotter"是正确的绘图仪名称,但无论哪种方式,我都需要一点帮助。

# doesn't work
dygraph(lungDeaths) %>% 
  dyBarChart() %>% 
  dySeries("ldeaths", plotter = "linePlotter")

# also doesn't work:
dygraph(lungDeaths) %>%
  dySeries("ldeaths", plotter = "dyBarChart") %>%
  dySeries("mdeaths", color = "blue")
Run Code Online (Sandbox Code Playgroud)

谢谢。

use*_*236 4

有时你很幸运\xe2\x80\xa6 我\xe2\x80\x98几周前也做过同样的事情,我\xe2\x80\x98ve发现文档不太清楚如何做。但你自己也很接近。

\n\n

如何一步步执行\xe2\x80\x93:

\n\n
    \n
  1. 您必须为每个dyseries设置绘图仪
  2. \n
  3. Dyseries 命令中的参数plotter不采用函数名称。但它必须是纯文本形式的 JavaScript 函数
  4. \n
  5. 堆叠酒吧更容易。Multibars 需要一种将参数传递给 javascript 函数的方法,而您无法直接在包中执行此操作。所以我必须采取一种解决方法(至少我在 R 中没有找到更好的方法)。
  6. \n
\n\n

顺便说一句,设置该dyPlotter命令不起作用,因为它为绘图中的所有 dySeries 全局设置绘图仪。至少我认为\xe2\x80\x98是它的作用。

\n\n

言归正传,这里\xe2\x80\x98是我的代码。我添加了一些更多的测试数据只是为了显示所有功能。

\n\n

测试数据:

\n\n
library(xts)\nlibrary(dygraphs)\ntest<-xts(matrix(rnorm(100*4), ncol=4, nrow=100), order.by=seq.POSIXt(as.POSIXct("2017-01-01 00:00", tz="UTC"),by=3600, length.out = 100))\ncolnames(test)<-c("Series_A","Series_B", "Series_C", "Series_D")\n
Run Code Online (Sandbox Code Playgroud)\n\n

功能:

\n\n
dy_position<-function(data_final, plot_title, y2_names=NULL, y1_label, y2_label, y1_step=F, y2_step=F, stacked=T){\n\n  data_final<-reorder_xts(data_final, y2_names) #reorder necessary so that all y2 are at the right end of the xts. Needed for the multibar plot\n\n  dyg <- dygraphs::dygraph(data_final, main=plot_title)\n  dyg <- dygraphs::dyAxis(dyg, "x", rangePad=20)\n  dyg <- dygraphs::dyAxis(dyg, "y", label = y1_label,\n                      axisLabelWidth = 90)\n  y1_names<-colnames(data_final)[!(colnames(data_final) %in%y2_names)]\n\n  if (length(y1_names)==1){\n    stacked<-T #in this case only stacking works\n  }\n\n  if (stacked){\n    dyg <- dygraphs::dyOptions(dyg,stepPlot=y1_step,stackedGraph = T)\n    for(i in seq_along(y1_names)) {\n     dyg <- dygraphs::dySeries(dyg, y1_names[i], axis = "y", strokeWidth = 1.5, stepPlot = y1_step, plotter="  function barChartPlotter(e) {\n                            var ctx = e.drawingContext;\n                            var points = e.points;\n                            var y_bottom = e.dygraph.toDomYCoord(0);\n\n                            ctx.fillStyle = e.color;\n\n                            // Find the minimum separation between x-values.\n                            // This determines the bar width.\n                            var min_sep = Infinity;\n                            for (var i = 1; i < points.length; i++) {\n                            var sep = points[i].canvasx - points[i - 1].canvasx;\n                            if (sep < min_sep) min_sep = sep;\n                            }\n                            var bar_width = Math.floor(2.0 / 3 * min_sep);\n\n                            // Do the actual plotting.\n                            for (var i = 0; i < points.length; i++) {\n                            var p = points[i];\n                            var center_x = p.canvasx;\n\n                            ctx.fillRect(center_x - bar_width / 2, p.canvasy,\n                            bar_width, y_bottom - p.canvasy);\n\n                            ctx.strokeRect(center_x - bar_width / 2, p.canvasy,\n                            bar_width, y_bottom - p.canvasy);\n                            }\n}")\n    }\n  } else {\n    dyg <- dygraphs::dyOptions(dyg,stepPlot=y1_step)\n    for(i in seq_along(y1_names)) {\n\n      #plotter in function\n      dyg <- dygraphs::dySeries(dyg, y1_names[i], axis = "y", strokeWidth   = 1.5, stepPlot = y1_step, plotter =multibar_combi_plotter(length(y2_names)))\n    }\n  }\n\n  # put stuff on y2 axis\n  dyg <- dygraphs::dyAxis(dyg, "y2", label = y2_label, independentTicks = T)\n  for(i in seq_along(y2_names)) {\n    dyg <- dygraphs::dySeries(dyg, y2_names[i], axis = "y2", strokeWidth = 1.5, stepPlot = y2_step)\n  }\n\n  return(dyg)\n}\n\n#we need to take into account all values and then leave out the ones we do not like\nmultibar_combi_plotter<-function(num_values){\n  #plotter function\n  plotter_text<-"function multiColumnBarPlotter(e) {\n  // We need to handle all the series simultaneously.\n  if (e.seriesIndex !== 0) return;\n\n  var g = e.dygraph;\n  var ctx = e.drawingContext;\n  var sets = e.allSeriesPoints;\n  var y_bottom = e.dygraph.toDomYCoord(0);\n\n  // Find the minimum separation between x-values.\n  // This determines the bar width.\n  var min_sep = Infinity;\n   for (var j = 0; j < sets.length-%s; j++) {\n    var points = sets[j];\n    for (var i = 1; i < points.length; i++) {\n     var sep = points[i].canvasx - points[i - 1].canvasx;\n     if (sep < min_sep) min_sep = sep;\n  }\n  }\n  var bar_width = Math.floor(2.0 / 3 * min_sep);\n\n  var fillColors = [];\n  var strokeColors = g.getColors();\n  for (var i = 0; i < strokeColors.length; i++) {\n  fillColors.push(strokeColors[i]);\n  }\n\n  for (var j = 0; j < sets.length-%s; j++) {\n  ctx.fillStyle = fillColors[j];\n  ctx.strokeStyle = strokeColors[j];\n  for (var i = 0; i < sets[j].length; i++) {\n    var p = sets[j][i];\n    var center_x = p.canvasx;\n    var x_left = center_x - (bar_width / 2) * (1 - j/(sets.length-%s-1));\n\n   ctx.fillRect(x_left, p.canvasy,\n   bar_width/sets.length, y_bottom - p.canvasy);\n\n  ctx.strokeRect(x_left, p.canvasy,\n  bar_width/sets.length, y_bottom - p.canvasy);\n }\n }\n   }"\n\n  custom_plotter <- sprintf(plotter_text, num_values, num_values, num_values)\n  return(custom_plotter)\n  }\n\n\nreorder_xts<-function(xts_series,line_names){\n  bar_names<-colnames(xts_series)[!(colnames(xts_series)%in%line_names)]\n  xts_series<-xts_series[,c(bar_names,line_names)]\n  return(xts_series)\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

一些解释:

\n\n

dy_position完成所有的策划工作。它在每个系列轴上使用单独的绘图仪。

\n\n

reorder_xts需要确保所有线图都位于 xts 的右端。这是多条形图所需要的。因为java脚本循环遍历所有系列(集合)以确定条形的宽度,并且我们需要确保我们没有循环遍历线图系列。否则我们还有额外的酒吧。

\n\n

multibar_combi_plotter正是这样做的。它采用数字参数lines_names并修改 javascript 字符串,以便它循环遍历除 line_names 之外的所有绘图(即 xts 右侧部分的最后一个系列)。%s请注意命令字符串中的几个小字符sprintfcharacter然后它返回dySeries 参数的绘图仪。

\n\n

所有 javascript 代码均直接取自 dygraphs 文件夹中的示例。

\n\n

这里有些例子...

\n\n

例子:

\n\n
dy_position(test,plot_title = "Test1", y2_names =    c("Series_C","Series_D"),y1_label = "Axis1", y2_label = "Axis2", stacked=F)\ndy_position(test,plot_title = "Test1", y2_names = c("Series_C","Series_D"),y1_label = "Axis1", y2_label = "Axis2", stacked=T)\ndy_position(test,plot_title = "Test1", y2_names = c("Series_B","Series_C","Series_D"),y1_label = "Axis1", y2_label = "Axis2", stacked=T)\ndy_position(test,plot_title = "Test1", y2_names = c("Series_D"),y1_label = "Axis1", y2_label = "Axis2", stacked=F)\ndy_position(test,plot_title = "Test1", y2_names = c("Series_D"),y1_label = "Axis1", y2_label = "Axis2", stacked=T)\ndy_position(test,plot_title = "Test1", y2_names = NULL ,y1_label = "Axis1", y2_label = "Axis2", stacked=F)\ndy_position(test,plot_title = "Test1", y2_names = NULL ,y1_label = "Axis1", y2_label = "Axis2", stacked=T)\n
Run Code Online (Sandbox Code Playgroud)\n