Draw heatmap for a matrix using circle in R [duplicate] - r

Is it possible to draw a heatmap with circles instead of square in ggplot2? It would be neat to not only represent the values by a color gradient but also by the circle size.
I am thinking of a graph like this dot heatmap where also the circle sizes are alternated by their specific value. I already read myself into heatmapping with ggplot2 but couldn't find a solution. For heatmapping I alternated the example posted on learnr.wordpress.com to:
library(ggplot2)
library(plyr)
library(reshape2)
library(scales)
kreuz <- read.csv("http://datasets.flowingdata.com/ppg2008.csv")
kreuz.m <- melt(kreuz)
(p <- ggplot(kreuz.m, aes(Name, variable)) +
geom_tile(aes(fill = value), colour = "white") +
scale_fill_gradient2(breaks=waiver(), name="binding strength",
low ="white", mid= ("lightblue"), high = "steelblue", midpoint = 4))
base_size <- 10
p + theme_grey(base_size = base_size) +
theme(panel.grid.major = element_blank())+
labs(x = "Patient ID", y = "Phage Motives", title = "Cross Reactivity")+
scale_x_discrete(expand = c(0, 0)) +
scale_y_discrete(expand = c(0, 0)) +
theme(legend.position = "right", axis.ticks = element_blank(),
axis.text.x = element_text(size = base_size *0.8, angle = 270, hjust = 0,
colour = "grey50"))+
labs(x = "Patient ID", y = "Phagemotives", title = "cross reactivity")
I would be very greatful for some hints!

In this example size and colour both correspond with the variable value because it's the only variable numeric available in the kreuz.m dataset.
ggplot(kreuz.m, aes(Name, variable)) +
geom_point(aes(size = value, colour=value))

Related

How do i change the legend label on ggplot, geom_point? [duplicate]

I have spent hours looking in the documentation and on StackOverflow, but no solution seems to solve my problem. When using ggplot I can't get the right text in the legend, even though it's in my dataframe. I have tried scale_colour_manual, scale_fill_manual with different values for labels= such as c("T999", "T888")", "cols".
Here is my code:
T999 <- runif(10, 100, 200)
T888 <- runif(10, 200, 300)
TY <- runif(10, 20, 30)
df <- data.frame(T999, T888, TY)
ggplot(data = df, aes(x=T999, y=TY, pointtype="T999")) +
geom_point(size = 15, colour = "darkblue") +
geom_point(data = df, aes(x=T888, y=TY), colour = 'red', size = 10 ) +
theme(axis.text.x = element_text(size = 20), axis.title.x =element_text(size = 20), axis.text.y = element_text(size = 20)) +
xlab("Txxx") + ylab("TY [°C]") + labs(title="temperatures", size = 15) +
scale_colour_manual(labels = c("T999", "T888"), values = c("darkblue", "red")) + theme(legend.position="topright")
Help would be very appreciated!
The tutorial #Henrik mentioned is an excellent resource for learning how to create plots with the ggplot2 package.
An example with your data:
# transforming the data from wide to long
library(reshape2)
dfm <- melt(df, id = "TY")
# creating a scatterplot
ggplot(data = dfm, aes(x = TY, y = value, color = variable)) +
geom_point(size=5) +
labs(title = "Temperatures\n", x = "TY [°C]", y = "Txxx", color = "Legend Title\n") +
scale_color_manual(labels = c("T999", "T888"), values = c("blue", "red")) +
theme_bw() +
theme(axis.text.x = element_text(size = 14), axis.title.x = element_text(size = 16),
axis.text.y = element_text(size = 14), axis.title.y = element_text(size = 16),
plot.title = element_text(size = 20, face = "bold", color = "darkgreen"))
this results in:
As mentioned by #user2739472 in the comments: If you only want to change the legend text labels and not the colours from ggplot's default palette, you can use scale_color_hue(labels = c("T999", "T888")) instead of scale_color_manual().
The legend titles can be labeled by specific aesthetic.
This can be achieved using the guides() or labs() functions from ggplot2 (more here and here). It allows you to add guide/legend properties using the aesthetic mapping.
Here's an example using the mtcars data set and labs():
ggplot(mtcars, aes(x=mpg, y=disp, size=hp, col=as.factor(cyl), shape=as.factor(gear))) +
geom_point() +
labs(x="miles per gallon", y="displacement", size="horsepower",
col="# of cylinders", shape="# of gears")
Answering the OP's question using guides():
# transforming the data from wide to long
require(reshape2)
dfm <- melt(df, id="TY")
# creating a scatterplot
ggplot(data = dfm, aes(x=TY, y=value, color=variable)) +
geom_point(size=5) +
labs(title="Temperatures\n", x="TY [°C]", y="Txxx") +
scale_color_manual(labels = c("T999", "T888"), values = c("blue", "red")) +
theme_bw() +
guides(color=guide_legend("my title")) # add guide properties by aesthetic

Radial plot using ggplot2

I'm trying to create piechart similar to radial plot (plotrix), in ggplot2.
Basically the slices would have different length.
radii <- c(2,3,2,1,3,1,2,3,2)
color <- c("lightgrey", "chartreuse", "lightgrey", "darkturquoise", "darkolivegreen3",
"orangered", "lightgrey", "darkseagreen1", "lightgrey")
radial.pie(radii, labels = NA, sector.colors = color,
show.grid = F, show.grid.labels = F ,show.radial.grid = T,
radial.labels = F, clockwise = T,start=3)
Is there an easy way to do this? The reason for doing it in ggplot is that I want to have a this piechart on top of a ggplot violin plot in one page using plot_grid.
This answer was copied from:
Making polar plots with ggplot2
by Carolyn Parkinson
(April 10, 2015)
http://rstudio-pubs-static.s3.amazonaws.com/72298_c1ba7f77276a4f27a0f375cadc9fac5d.html
Basically, all you have to do is plot a bar plot with coord_ploar() to make it this kind of radial plot:
require(ggplot2)
# function to compute standard error of mean
se <- function(x) sqrt(var(x)/length(x))
set.seed(9876)
DF <- data.frame(variable = as.factor(1:10),
value = sample(10, replace = TRUE))
ggplot(DF, aes(variable, value, fill = variable)) +
geom_bar(width = 1, stat = "identity", color = "white") +
geom_errorbar(aes(ymin = value - se(DF$value),
ymax = value + se(DF$value),
color = variable),
width = .2) +
scale_y_continuous(breaks = 0:nlevels(DF$variable)) +
theme_gray() +
theme(axis.ticks = element_blank(),
axis.text = element_blank(),
axis.title = element_blank(),
axis.line = element_blank()) +
coord_polar()

ggplot2, facet wrap, fixed y scale for each row, free scale between rows

I would like to produce a plot using facet_wrap that has a different y scale for each row of the wrap. In other words, with fixed scales on the same row, free scales on different rows, with a fixed x scale. Free scales doesn't give me exactly what I'm looking for, nor does facet_grid. If possible, I'd like to avoid creating 2 separate plots and then pasting them together. I'm looking for a result like the plot below, but with a y scale max of 300 for the first row, and an y scale max of 50 in the second row. Thanks for any help!
Here is my code:
library(ggplot2)
library(reshape)
# set up data frame
dat <- data.frame(jack = c(150,160,170),
surgeon = c(155,265,175),
snapper = c(10,15,12),
grouper = c(5,12,50))
dat$island<-c("Oahu","Hawaii","Maui")
df<-melt(dat)
# plot
ggplot(df, aes(fill=variable, y=value, x=island)) +
geom_bar(width = 0.85, position= position_dodge(width=0.5),stat="identity", colour="black") +
facet_wrap(~variable, scales = "free_y",ncol=2) +
theme_bw() +
theme(strip.text = element_text(size=15, face="bold"))+
theme(legend.position="none")+
theme(panel.grid.major = element_line(colour = "white", size = 0.2))+
theme(panel.grid.minor = element_line(colour = "white", size = 0.5))+
theme(axis.text.x = element_text(angle = 90, hjust =1, vjust =0.5, size=18))+
labs(y = expression(paste("Yearly catch (kg)")))
Drawing on one of the lower ranked answers from the link Eric commented, you can add a layer that blends into the background to enforce the axes.
Here I created a second data frame (df2) that puts a single point at "Hawaii" and the max value you wanted (300 or 50) for the four variable/fish types. By manually setting the color of the geom_point white, it fades into the background.
library(ggplot2)
library(reshape)
# set up data frame
dat <- data.frame(jack = c(150,160,170),
surgeon = c(155,265,175),
snapper = c(10,15,12),
grouper = c(5,12,50))
dat$island<-c("Oahu","Hawaii","Maui")
df<-melt(dat)
#> Using island as id variables
df2 <- data.frame(island = rep("Hawaii",4), variable = c("jack","surgeon","snapper","grouper"),value = c(300,300,50,50))
ggplot(df, aes(fill=variable, y=value, x=island)) +
geom_bar(width = 0.85, position= position_dodge(width=0.5),stat="identity", colour="black") +
geom_point(data = df2, aes(x = island, y = value), colour = "white") +
facet_wrap(~variable, scales = "free_y",ncol=2) +
theme_bw() +
theme(strip.text = element_text(size=15, face="bold"))+
theme(legend.position="none")+
theme(panel.grid.major = element_line(colour = "white", size = 0.2))+
theme(panel.grid.minor = element_line(colour = "white", size = 0.5))+
theme(axis.text.x = element_text(angle = 90, hjust =1, vjust =0.5, size=18))+
labs(y = expression(paste("Yearly catch (kg)")))

Merging two plots into one, each with a separate legend using R

I'm have made two separate scatter plots using ggplot2 and I need to combine them into one single plot. Each plot is for a population of lizards under three different treatments (backgrounds).
for each plot I have the following:
csMS = data.frame()
ellMS = data.frame()
centroidsMS = data.frame()
csplotMS = ggplot(csMS, aes(x = RG, y = GB, colour = Background)) + geom_point(size = 3, shape = 17) + #colour by background, circles size 3
geom_path(data = ell.AS, aes(x = RG, y = GB ,colour = Background), size = 1, linetype = 2) + #adding the ellipses
geom_point(data = centroidsMS, size = 3, shape = 17) + #added centroids
geom_errorbar(data = centroidsMS, aes(ymin = GB - se.GB, ymax = GB + se.GB), width = 0) + #add y error bars
geom_errorbarh(data = centroidsMS, aes(xmin = RG - se.RG, xmax = RG + se.RG), height = 0) +
theme_bw() + #white background
theme(axis.title.y = element_text(vjust = 2), axis.title.x = element_text(vjust = -0.3)) + #distance of axis titles from axis
theme(panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), #no grids
axis.line = element_line(colour = "black")) + #black axes
theme(text = element_text(size = 30)) + #font size
ylab("(G-B)/(G+B)") + xlab("(R-G)/(R+G)") + # Set text for axes labels
scale_colour_manual(values = c("black","#FF6600", "yellow1")) + #changed default colours
labs(colour = "Murray Sunset NP") +
theme(legend.title = element_text(size = "20")) + #changes the legend title
theme(legend.text = element_text(size = "20")) + #changes the legend title
theme(legend.key = element_blank()) + #removed little squares around legend symbols
theme(legend.direction = "horizontal", legend.position = c(.5, .85))
I tried
csASMS = csplotAS + csplotMS
but I get an error message: "Error in p + o : non-numeric argument to binary operator In addition: Warning message: Incompatible methods ("+.gg", "Ops.data.frame") for "+" "
I also tried
csASMS = grid.arrange(csplotAS, csplotMS)
but this places one plot on top of the other, but I need to combine both plots so that they are basically just one plot but with two separate legends as each plot has different conventions to indicate the different lizard populations.
Any help will be greatly appreciated.
****EDIT**** Dec 12/ 2014
I have managed to combine the two plots into one but still have the problem of the separate legends. To try to simplify the question and as per cdeterman's request I'm adding a simpler form of the code with some sample data:
data frames: p1 and p2
> p1
treatment x y
1 Black 1 1
2 Orange 2 2
3 Yellow 3 3
> p2
treatment x y
1 Black 4 4
2 Orange 5 5
3 Yellow 6 6
I used the following code to make a plot that includes both data frames:
plot = ggplot(p1, aes(x = x, y = y, colour = treatment)) + geom_point(size = 3) + #colour by background, circles size 3
theme_bw() + #white background
theme(axis.title.y = element_text(vjust = 2), axis.title.x = element_text(vjust = -0.3)) + #distance of axis titles from axis
theme(panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), #no grids
axis.line = element_line(colour = "black")) + #black axes
theme(text = element_text(size = 30)) + #font size
scale_colour_manual(values = c("black","#FF6600", "yellow1")) + #changed default colours
labs(colour = "p1") +
theme(legend.title = element_text(size = "20")) + #changes the legend title
theme(legend.text = element_text(size = "20")) + #changes the legend title
theme(legend.key = element_blank()) + #removed little squares around legend symbols
theme(legend.direction = "horizontal", legend.position = c(.33, 1)) +
# Now to add the second plot/ No need to code for axis titles, titles positions,etc b/c it's already coded in the first plot
geom_point(data = p2, aes(x = x, y = y, colour = treatment), size = 3, shape = 17)
This produces a graph with each data frame represented in a different symbol (circles for p1 and triangles for p2) but with only one combined legend with triangles superimposed over circles). How can I get two separate legends, one for each data frame?
Thank you!
After doing some research and trying different things I was able to solve PART of my problem. To add two plots together one needs to be plotter first and the other one on top of the first one using
geom.point()
my new code looks like this:
csplotASMS = ggplot(csAS, aes(x = RG, y = GB, colour = Background)) + geom_point(size = 3) + #colour by background, circles size 3
geom_path(data = ell.AS, aes(x = RG, y = GB ,colour = Background), size = 1, linetype = 1) + #adding the ellipses
geom_point(data = centroidsAS, size = 4) + #added centroids
geom_errorbar(data = centroidsAS, aes(ymin = GB - se.GB, ymax = GB + se.GB), width = 0) + #add y error bars
geom_errorbarh(data = centroidsAS, aes(xmin = RG - se.RG, xmax = RG + se.RG), height = 0) +
theme_bw() + #white background
theme(axis.title.y = element_text(vjust = 2), axis.title.x = element_text(vjust = -0.3)) + #distance of axis titles from axis
theme(panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), #no grids
axis.line = element_line(colour = "black")) + #black axes
theme(text = element_text(size = 30)) + #font size
ylab("(G-B)/(G+B)") + xlab("(R-G)/(R+G)") + # Set text for axes labels
scale_colour_manual(values = c("black","#FF6600", "yellow1")) + #changed default colours
labs(colour = "Alice Springs") +
theme(legend.title = element_text(size = "20")) + #changes the legend title
theme(legend.text = element_text(size = "20")) + #changes the legend title
theme(legend.key = element_blank()) + #removed little squares around legend symbols
theme(legend.direction = "horizontal", legend.position = c(.33, 1)) +
# Now to add the second plot/ No need to code for axis titles, titles positions,etc b/c it's already coded in the first plot
geom_point(data = csMS, aes(x = RG, y = GB, colour = Background), size = 3, shape = 17) +
geom_path(data = ell.MS, aes(x = RG, y = GB ,colour = Background), size = 1, linetype = 2) + #adding the ellipses
geom_point(data = centroidsMS, size = 4, shape = 17) + #added centroids
geom_errorbar(data = centroidsMS, aes(ymin = GB - se.GB, ymax = GB + se.GB), width = 0) + #add y error bars
geom_errorbarh(data = centroidsMS, aes(xmin = RG - se.RG, xmax = RG + se.RG), height = 0) #add x error bars
and the graph depicts a scatterplot for two populations, each with three treatments. Because tratments are the same for both populations I want to use the same colours but different symbols to denote the differences in populations. One population is circles and the other one is triangles.
Now, the part I can't answer yet is how to have two separate legends, one for each "plot". i.e. one for the circles and one for the triangles. At the moments there is a "combined legend showing triangles superimposed on circles. Each legend should have its own title.

Is a heatmap in "sized dot style" possible in ggplot2?

Is it possible to draw a heatmap with circles instead of square in ggplot2? It would be neat to not only represent the values by a color gradient but also by the circle size.
I am thinking of a graph like this dot heatmap where also the circle sizes are alternated by their specific value. I already read myself into heatmapping with ggplot2 but couldn't find a solution. For heatmapping I alternated the example posted on learnr.wordpress.com to:
library(ggplot2)
library(plyr)
library(reshape2)
library(scales)
kreuz <- read.csv("http://datasets.flowingdata.com/ppg2008.csv")
kreuz.m <- melt(kreuz)
(p <- ggplot(kreuz.m, aes(Name, variable)) +
geom_tile(aes(fill = value), colour = "white") +
scale_fill_gradient2(breaks=waiver(), name="binding strength",
low ="white", mid= ("lightblue"), high = "steelblue", midpoint = 4))
base_size <- 10
p + theme_grey(base_size = base_size) +
theme(panel.grid.major = element_blank())+
labs(x = "Patient ID", y = "Phage Motives", title = "Cross Reactivity")+
scale_x_discrete(expand = c(0, 0)) +
scale_y_discrete(expand = c(0, 0)) +
theme(legend.position = "right", axis.ticks = element_blank(),
axis.text.x = element_text(size = base_size *0.8, angle = 270, hjust = 0,
colour = "grey50"))+
labs(x = "Patient ID", y = "Phagemotives", title = "cross reactivity")
I would be very greatful for some hints!
In this example size and colour both correspond with the variable value because it's the only variable numeric available in the kreuz.m dataset.
ggplot(kreuz.m, aes(Name, variable)) +
geom_point(aes(size = value, colour=value))

Resources