19

Assume there is a dataset in polar coordinate to be plotted as sector

library(ggplot2)
library(reshape2)
data <- melt(matrix(rnorm(1000), nrow = 20))
data$type <- 1:2
data$Var1 <- data$Var1*6 - 60

ggplot(data, aes(Var1, Var2)) + 
  geom_tile(aes(fill = value)) + 
  coord_polar(theta = "x", start = pi) + 
  scale_x_continuous(limits = c(-180, 180)) +
  facet_wrap(~type)

which gives the following graph: enter image description here

How can we remove the bottom (blank) part of the plot while not making a full circle?

tonytonov
  • 25,060
  • 16
  • 82
  • 98
Ravat
  • 207
  • 2
  • 8
  • 2
    I doubt there is a way to do this with ggplot2. I think it might even be quite a bit of work if you make it a grob and hack away at the grid level. I would look for a different approach. – Roland Mar 14 '14 at 09:14
  • I agree with @Roland. Two options that come in my mind: 1) Could you use `coord_cartesian` for your data? If not, and if you want to use `ggplot2`, using an image manipulation program to crop the plot would likely be the easiest solution. You could of course do the same in R, but that would require some hacking as Roland says. – Mikko Mar 14 '14 at 10:43
  • I haven't tried it but what about moving the legend up and then constraining the lower plot margin to a negative value? – Tyler Rinker Mar 14 '14 at 13:40

2 Answers2

12

This is an inelegant hack, but you can use grid functions to cover up the area you don't want. For example:

library(ggplot2)
library(reshape2)
library(grid)

data <- melt(matrix(rnorm(1000), nrow = 20))
data$type <- 1:2
data$Var1 <- data$Var1*6 - 60

p1 = ggplot(data, aes(Var1, Var2)) + 
  geom_tile(aes(fill = value)) + 
  coord_polar(theta = "x", start = pi) + 
  scale_x_continuous(limits = c(-180, 180)) +
  facet_wrap(~type)
g1 = ggplotGrob(p1)

grid.newpage()
pushViewport(viewport(height=1, width=1, clip="on"))
grid.draw(g1)
grid.rect(x=0,y=0,height=1, width=2, gp=gpar(col="white"))

This cuts off the bottom half of the graph (see below). It would be nice to find a more elegant approach, but failing that, maybe you can play around with viewport placement and drawing functions (not to mention changing the location of the axis labels and legend) to get something close to what you want. enter image description here

eipi10
  • 91,525
  • 24
  • 209
  • 285
2

Here's a cleaner solution with ggtrace (originally posted on twitter).

library(ggplot2)
#> Warning: package 'ggplot2' was built under R version 4.1.2
library(ggtrace)
library(reshape2)
data <- melt(matrix(rnorm(1000), nrow = 20))
data$type <- 1:2
data$Var1 <- data$Var1*6 - 60

p <- ggplot(data, aes(Var1, Var2)) + 
  geom_tile(aes(fill = value)) + 
  coord_polar(theta = "x", start = pi) + 
  scale_x_continuous(limits = c(-180, 180)) +
  facet_wrap(~type)

with_ggtrace(
  x = p + theme(aspect.ratio = .52),
  method = Layout$render,
  trace_steps = 5L,
  trace_expr = quote({
    panels <- lapply(panels, editGrob, vp = viewport(yscale = c(0.48, 1)))
  }),
  out = "g"
)

Created on 2022-03-24 by the reprex package (v2.0.1)

MSB
  • 86
  • 4