1

I want to add another legend that tells me what ring of a circular heat map represents (from outer ring to inner ring).

I tried the following from another answer previously:

library(reshape)
library(ggplot2)
library(plyr)

nba <- read.csv("http://datasets.flowingdata.com/ppg2008.csv")

nba$Name <- with(nba, reorder(Name, PTS))
nba.m <- melt(nba)

nba.m <- ddply(nba.m, .(variable), transform, value = scale(value))

# Convert the factor levels (variables) to numeric + quanity to determine    size   of hole.
nba.m$var2 = as.numeric(nba.m$variable) + 15

# Labels and breaks need to be added with scale_y_discrete.
y_labels = levels(nba.m$variable)
y_breaks = seq_along(y_labels) + 15


nba.labs <- subset(nba.m, variable==levels(nba.m$variable)    [nlevels(nba.m$variable)])

nba.labs <- nba.labs[order(nba.labs$Name),]
nba.labs$ang <- seq(from=(360/nrow(nba.labs))/1.5, to=(1.5* (360/nrow(nba.labs)))-360, length.out=nrow(nba.labs))+80
nba.labs$hjust <- 0
nba.labs$hjust[which(nba.labs$ang < -90)] <- 1
nba.labs$ang[which(nba.labs$ang < -90)] <- (180+nba.labs$ang)[which(nba.labs$ang < -90)]

p2 = ggplot(nba.m, aes(x=Name, y=var2, fill=value)) +
  geom_tile(colour="white") +
  geom_text(data=nba.labs, aes(x=Name, y=var2+1.5,
                           label=Name, angle=ang, hjust=hjust), size=3) +
  scale_fill_gradient(low = "white", high = "steelblue") +
  ylim(c(0, max(nba.m$var2) + 1.5)) +
  scale_y_discrete(breaks=y_breaks, labels=y_labels) +
  coord_polar(theta="x") +
  theme(panel.background=element_blank(),
    axis.title=element_blank(),
    panel.grid=element_blank(),
    axis.text.x=element_blank(),
    axis.ticks=element_blank(),
    axis.text.y=element_text(size=5))
print(p2)

However, instead of getting the legend, I'm having this error message instead:

Scale for 'y' is already present. Adding another scale for 'y', which will replace the existing scale.

Any solutions?

Thanks in advance!

Community
  • 1
  • 1
Miyii
  • 141
  • 1
  • 1
  • 8
  • which line of your code adds another legend? – Sandipan Dey Jan 06 '17 at 06:42
  • I have this code from here: http://stackoverflow.com/questions/13887365/ggplot2-circular-heatmap-that-looks-like-a-donut Initially, I thought this scale_y_discrete(breaks=y_breaks, labels=y_labels) would be the other legend (left hand corner, in grey), but it does not work.. – Miyii Jan 06 '17 at 06:46
  • That doesn't appear to be an error, its a warning (delete ``scale_y_discrete(breaks=y_breaks, labels=y_labels) +`` to get rid tho unnecessary). Also, it should be noted you need to load `plyr` for `ddply`. Anyways, your explanation "legend that tells me what ring of a circular heat map represents" doesn't quite make sense to me. Perhaps thats my own ignorance, do you have an example of what you're looking for? Are the rings numbered? If so that requires additional code and its a different question than what you've asked. – Cyrus Mohammadian Jan 06 '17 at 07:13
  • Hi @CyrusMohammadian, I have deleted " scale_y_discrete(breaks=y_breaks, labels=y_labels) + "and the legend appears (however, with the wrong label). And yes, I did forget to add the code for loading plyr. Thanks for the reminder! An example is on this site [link] http://stackoverflow.com/questions/13887365/ggplot2-circular-heatmap-that-looks-like-a-donut. The "legend" is on the first image, left hand corner. I can't seem to get the right labels after deleting "scale_y_discrete(breaks=y_breaks, labels=y_labels) +" though.. :) – Miyii Jan 06 '17 at 08:39
  • @Miyii what labels are you looking for? – Cyrus Mohammadian Jan 07 '17 at 02:14
  • @CyrusMohammadian The labels for nba.m$variables :) – Miyii Jan 07 '17 at 08:54
  • @Miyii for the record, that's not a "legend" you're referring to in you question. It's the y-axis. – Cyrus Mohammadian Feb 08 '17 at 23:31

1 Answers1

1

It's not entirely clear to me what you're looking for but this may be it. You were originally using scale_y_discrete(breaks=y_breaks, labels=y_labels) to project to a continuous variable,var2, in aes(x=Name, y=var2, fill=value). By changing that to scale_y_continuous(breaks=y_breaks, labels=y_labels) you can get the categorical labels listed for nba.m$variable.

ggplot(nba.m, aes(x=Name, y=var2, fill=value)) +
  geom_tile(colour="white") +
  geom_text(data=nba.labs, aes(x=Name, y=var2+1.5,
                           label=Name, angle=ang, hjust=hjust), size=3) +
  scale_fill_gradient(low = "white", high = "steelblue") +
  ylim(c(0, max(nba.m$var2) + 1.5)) +
  scale_y_continuous(breaks=y_breaks, labels=y_labels) +
  coord_polar(theta="x") +
  theme(panel.background=element_blank(),
    axis.title=element_blank(),
    panel.grid=element_blank(),
    axis.text.x=element_blank(),
    axis.ticks=element_blank(),
    axis.text.y=element_text(size=5))

enter image description here

UPDATE

I'm not sure what you're trying to do here -those values are not blank in the center because there's data there, removing scale_y_continuous(breaks=y_breaks, labels=y_labels) limits the scale of the y-axis such that the date is no longer graphed. That's why you're not seeing the middle filled when that line of code is removed. At any rate, if that's what you're looking for, what you need to do is delete scale_y_continuous(breaks=y_breaks, labels=y_labels) and turn off the labels for the y-axis, then manually add those labels using grob. I'm sure there's a better way to accomplish what you need but this will get you started at least.

p<-ggplot(nba.m, aes(x=Name, y=var2, fill=value)) +
  geom_tile(colour="white") +
  geom_text(data=nba.labs, aes(x=Name, y=var2+1.5,
                           label=Name, angle=ang, hjust=hjust), size=2.5) +
  scale_fill_gradient(low = "white", high = "steelblue") +
  ylim(c(0, 50)) +
  coord_polar(theta="x") +
  theme(panel.background=element_blank(),
    axis.title=element_blank(),
    panel.grid=element_blank(),
    axis.text.x=element_blank(),
    axis.ticks=element_blank(),
    axis.text.y=element_text(size=5))+ theme(axis.title.y=element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank())
lab = textGrob((paste("G  MIN  PTS  FGM  FGA  FGP  FTM  FTA  FTP  X3PM X3PA X3PP ORB DRB  TRB  AST  STL  BLK  TO  PF")),
   x = unit(.1, "npc"), just = c("left"), 
   gp = gpar(fontsize = 7))

gp = ggplotGrob(p)
gp = gtable_add_rows(gp, unit(10, "grobheight", lab), -1)
gp = gtable_add_grob(gp, lab, t = -2, l = gp$layout[gp$layout$name == "panel",]$l)

grid.newpage()
grid.draw(gp)

enter image description here

Cyrus Mohammadian
  • 4,982
  • 6
  • 33
  • 62
  • Yes! I think we are almost there! One thing I realised though, is with the `nba.m$variable` labels appearing now, the "donut" (size of hole in the middle of the plot) seemed to disappear! This is resolved if `scale_y_continuous(breaks=y_breaks, labels=y_labels)` is commented out though (which then prevents the labels from appearing...) – Miyii Jan 15 '17 at 06:58
  • @Miyii, I'm sorry its unclear to me what the problem is or how the above plot doesn't conform to your needs... – Cyrus Mohammadian Jan 15 '17 at 18:31
  • something like the plot in this website [link](http://www.r-graph-gallery.com/128-ring-or-donut-plot/), whereby there is a hole in the middle of the plot. I've stated the hole to be size 15 in the script, but it doesn't appear. – Miyii Feb 07 '17 at 04:23