Search code examples
rgeometrypolygoncentroid

Center of gravity of barplot in R


Say you have a vector, and you make a barplot of it in R. How do you calculate the centroid / center of gravity of the barplot?

x<-cumsum(rnorm(50,1,2)) 
par(mfrow=c(1,2))
plot(x,type="l")
barplot(x)
par(mfrow=c(1,1))

There are plenty of answers on here about the center of gravity of a polygon, but I'm not sure which points I need to get the entire shape of the barplot, and not just the vector with the points (like in the left plot).


Solution

  • You can easily compute it using this function

    getCentroid <- function(x, width = 1) {
      A  <- x * width                  # area of each bar
      xc <- seq(width/2, length(x), 1) # x coordinates of center of bars
      yc <- x/2                        # y coordinatey
    
      cx <- sum(xc * A) / sum(A)
      cy <- sum(yc * A) / sum(A)
      return(list(x = cx, y = cy))
    }
    points(getCentroid(x), col = 'red', pch = 19)
    

    Notes: The default width of each bar is 1. The x coordinate of the centroid of two bars can be computed using the formula

    enter image description here

    The same applies to the y coordinate. This can be extended to a higher number of bars.

    enter image description here


    Since we do not have a perfect triangle, there will always be an error if we compare the centroids. Taking bars with the same height difference for example, like

    x <- seq(0, 1, length.out = 1000)
    

    (where the first bar has heigth 0) will always yield an error in the x coordinate of 1/6 (2000/3 compared to 666.83333) . The reason is the missing area due to the fact that we have no perfect triangle. This missing area equals 0.5 (Think about the height difference and multiply it by the bar width. Summing this over all bars and dividing it by 2 equals....).