【问题标题】:Vertical Histogram垂直直方图
【发布时间】:2012-10-30 22:03:22
【问题描述】:

我想做一个垂直直方图。理想情况下,我应该能够每天在一个地块上放置多个。

如果这可以与 quantmod 实验 chart_Series 或其他能够为时间序列绘制条形的库相结合,那就太好了。请参阅随附的屏幕截图。理想情况下,我可以绘制这样的图。

是否有任何内置或现有的库可以帮助解决这个问题?

【问题讨论】:

    标签: r quantmod


    【解决方案1】:

    大约一年前我写了一些东西来在基本图形中做垂直直方图。这是一个使用示例。

    VerticalHist <- function(x, xscale = NULL, xwidth, hist,
                             fillCol = "gray80", lineCol = "gray40") {
        ## x (required) is the x position to draw the histogram
        ## xscale (optional) is the "height" of the tallest bar (horizontally),
        ##   it has sensible default behavior
        ## xwidth (required) is the horizontal spacing between histograms
        ## hist (required) is an object of type "histogram"
        ##    (or a list / df with $breaks and $density)
        ## fillCol and lineCol... exactly what you think.
        binWidth <- hist$breaks[2] - hist$breaks[1]
        if (is.null(xscale)) xscale <- xwidth * 0.90 / max(hist$density)
        n <- length(hist$density)
        x.l <- rep(x, n)
        x.r <- x.l + hist$density * xscale
        y.b <- hist$breaks[1:n]
        y.t <- hist$breaks[2:(n + 1)]
    
        rect(xleft = x.l, ybottom = y.b, xright = x.r, ytop = y.t,
             col = fillCol, border = lineCol)
    }
    
    
    
    ## Usage example
    require(plyr) ## Just needed for the round_any() in this example
    n <- 1000
    numberOfHists <- 4
    data <- data.frame(ReleaseDOY = rnorm(n, 110, 20),
                       bin = as.factor(rep(c(1, 2, 3, 4), n / 4)))
    binWidth <- 1
    binStarts <- c(1, 2, 3, 4)
    binMids <- binStarts + binWidth / 2
    axisCol <- "gray80"
    
    ## Data handling
    DOYrange <- range(data$ReleaseDOY)
    DOYrange <- c(round_any(DOYrange[1], 15, floor),
                          round_any(DOYrange[2], 15, ceiling))
    
    ## Get the histogram obects
    histList <- with(data, tapply(ReleaseDOY, bin, hist, plot = FALSE,
        breaks = seq(DOYrange[1], DOYrange[2], by = 5)))
    DOYmean <- with(data, tapply(ReleaseDOY, bin, mean))
    
    ## Plotting
    par(mar = c(5, 5, 1, 1) + .1)
    plot(c(0, 5), DOYrange, type = "n",
         ann = FALSE, axes = FALSE, xaxs = "i", yaxs = "i")
    
    axis(1, cex.axis = 1.2, col = axisCol)
    mtext(side = 1, outer = F, line = 3, "Length at tagging (mm)",
          cex = 1.2)
    axis(2, cex.axis = 1.2, las = 1, line = -.7, col = "white",
        at = c(75, 107, 138, 169),
        labels = c("March", "April", "May", "June"), tck = 0)
    mtext(side = 2, outer = F, line = 3.5, "Date tagged", cex = 1.2)
    box(bty = "L", col = axisCol)
    
    ## Gridlines
    abline(h = c(60, 92, 123, 154, 184), col = "gray80")
    
    biggestDensity <- max(unlist(lapply(histList, function(h){max(h[[4]])})))
    xscale <- binWidth * .9 / biggestDensity
    
    ## Plot the histograms
    for (lengthBin in 1:numberOfHists) {
        VerticalHist(binStarts[lengthBin], xscale = xscale,
                             xwidth = binWidth, histList[[lengthBin]])
        }
    

    【讨论】:

    • 我真的觉得这很有用,并最终编写了一个包装器以更灵活的方式使用它。发布在github.com/ozgen92/VerticalHist,希望你不要介意:)
    • 谢谢!我不介意,但如果能在自述文件末尾的一行或代码中的注释说 “基于 Gregor Thomas 创建的 Stack Overflow 答案:@ 987654322@"
    • 当然,很抱歉一开始没有添加它。这是我第一次改进别人的代码,所以没有抄袭的意图,只是分享以便其他人可以即插即用
    【解决方案2】:

    小提琴情节可能与您想要的足够接近。它们是通过一个轴镜像的密度图,就像箱线图和密度图的混合体。 (通过示例比描述更容易理解。:-))

    这是一个简单的(有点丑陋的)ggplot2 实现示例:

    library(ggplot2)
    library(lubridate)
    
    data(economics) #sample dataset
    
    # calculate year to group by using lubridate's year function
    economics$year<-year(economics$date)
    
    # get a subset 
    subset<-economics[economics$year>2003&economics$year<2007,]    
    
    ggplot(subset,aes(x=date,y=unemploy))+
        geom_line()+geom_violin(aes(group=year),alpha=0.5)
    

    一个更漂亮的例子是:

    ggplot(subset,aes(x=date,y=unemploy))+ 
        geom_violin(aes(group=year,colour=year,fill=year),alpha=0.5, 
        kernel="rectangular")+    # passes to stat_density, makes violin rectangular 
        geom_line(size=1.5)+      # make the line (wider than normal)
        xlab("Year")+             # label one axis
        ylab("Unemployment")+     # label the other
        theme_bw()+                     # make white background on plot
        theme(legend.position = "none") # suppress legend
    

    要包括范围而不是线,您可以使用 geom_linerange 或 geom_pointrange。

    【讨论】:

      【解决方案3】:

      如果您使用网格图形,那么您可以在任何您想要的位置创建旋转的视口并绘制到旋转的视口。您只需要一个将使用网格图形绘制到指定视口的函数,我建议为此使用 ggplot2 或可能的 lattice。

      在基本图形中,您可以编写自己的函数来绘制旋转直方图(修改 plot.histogram 函数或使用rect 或其他工具从头开始编写自己的函数)。然后,您可以使用 TeachingDemos 包中的 subplot 函数将绘图放置在较大绘图上的任何位置。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-26
        • 2011-08-27
        • 2014-12-08
        • 2014-11-15
        相关资源
        最近更新 更多