i have two type of parameters and one response for one chemical compound:
The code used to generated this picture was
for (i in levels(data$ProteinName))
{
temp <- subset(data, data$ProteinName == i)
plot <- ggplot(data = temp, aes(x= temp$id, y = temp$Matrix))+
geom_tile( aes( fill= temp$TotalArea))+
labs(title= i, x = NULL, y = NULL, fill = "Average Total Area")+
geom_text(aes(label=round(TotalArea, digits = 0)), color = "White")+
scale_fill_gradientn (colors=c(low = "blue4", mid="gold", high = "red"),
na.value = "violetred")+
theme_bw()
print(plot)
}
but this is one of 12 plots so for my report i had to take it into a facet but i haven't found anny method to create a free scale for the "z axis" scale the current code is
temp <- data
plot <- ggplot(data = temp, aes(x= temp$id, y = temp$Matrix))+
facet_wrap(~temp$ProteinName, scale = "free")+
geom_tile( aes( fill= temp$TotalArea))+
labs(title= i, x = NULL, y = NULL, fill = "Average Total Area")+
geom_text(aes(label=round(TotalArea, digits = 0)), color = "White")+
scale_fill_gradientn (colors=c(low = "blue4", mid="gold", high = "red"),
na.value = "violetred")+
theme_bw()
print(plot)
and gives the follow:
but here is the color of the tiles (z axis) not free did any body know how to create a free z axis?
you can see ad the PE facet that it is only blue but within this facet there is a quite large difference with the observed concentration.
The goal is that te readers can see what is the larges respons (red) and the lowest (blue).
Hopefully you can help me.
Thanks for the answers,
with the help of the post:
Place a legend for each facet_wrap grid in ggplot2
it was verry easy done,
the old script was:
for (i in levels(data$ProteinName))
{
temp <- subset(data, data$ProteinName == i)
plot <- ggplot(data = temp, aes(x= temp$id, y = temp$Matrix))+
geom_tile( aes( fill= temp$TotalArea))+
labs(title= i, x = NULL, y = NULL, fill = "Average Total Area")+
geom_text(aes(label=round(TotalArea, digits = 0)), color = "White")+
scale_fill_gradientn (colors=c(low = "blue4", mid="gold", high = "red"),
na.value = "violetred")+
theme_bw()
print(plot)
}
with result:
old plot
after that we updated the script with the fucntion grid.arrange(grobs = list_of_plots) from the gridextra package
there for i had to make a list in the loop, this was done with: plot_v[[i]] <- plot, plot_v is the name of the list of plots.
this list was then added to the grid arrange
so the new script is now
require(gridExtra)
require(ggplot2)
plot_v <- list()
for (i in levels(data$ProteinName))
{
temp <- subset(data, data$ProteinName == i)
plot <- ggplot(data = temp, aes(x= temp$id, y = temp$Matrix))+
geom_tile( aes( fill= temp$TotalArea))+
labs(title= i, x = NULL, y = NULL, fill = "Average Total Area")+
geom_text(aes(label=round(TotalArea, digits = 0)), color = "White", size= 2.5)+
scale_fill_gradientn (colors=c(low = "blue4", mid="gold", high = "red"),
na.value = "violetred")+
theme_bw()+
guides(fill = "none")
print(plot)
assign(paste("plot", i, sep="_"), plot)
plot_v[[i]] <- plot
}
grid.arrange(grobs = plot_v)
this gives as result
new plot
I want to thank you for your help
Related
I have two very similar plots, which have two y-axis - a bar plot and a line plot:
code:
sec_plot <- ggplot(data, aes_string (x = year, group = 1)) +
geom_col(aes_string(y = frequency), fill = "orange", alpha = 0.5) +
geom_line(aes(y = severity))
However, there are no labels. I want to get a label for the barplot as well as a label for the line plot, something like:
How can I add the labels to the plot, if there is only pone single group? is there a way to specify this manually? Until know I have only found option where the labels can be added by specifying them in the aes
EXTENSION (added a posterior):
getSecPlot <- function(data, xvar, yvar, yvarsec, groupvar){
if ("agegroup" %in% xvar) xvar <- get("agegroup")
# data <- data[, startYear:= as.numeric(startYear)]
data <- data[!claims == 0][, ':=' (scaled = get(yvarsec) * max(get(yvar))/max(get(yvarsec)),
param = max(get(yvar))/max(get(yvarsec)))]
param <- data[1, param] # important, otherwise not found in ggplot
sec_plot <- ggplot(data, aes_string (x = xvar, group = groupvar)) +
geom_col(aes_string(y = yvar, fill = groupvar, alpha = 0.5), position = "dodge") +
geom_line(aes(y = scaled, color = gender)) +
scale_y_continuous(sec.axis = sec_axis(~./(param), name = paste0("average ", yvarsec),labels = function(x) format(x, big.mark = " ", scientific = FALSE))) +
labs(y = paste0("total ", yvar)) +
scale_alpha(guide = 'none') +
theme_pubclean() +
theme(legend.title=element_blank(), legend.background = element_rect(fill = "white"))
}
plot.ExposureYearly <- getSecPlot(freqSevDataAge, xvar = "agegroup", yvar = "exposure", yvarsec = "frequency", groupvar = "gender")
plot.ExposureYearly
How can the same be done on a plot where both the line plot as well as the bar plot are separated by gender?
Here is a possible solution. The method I used was to move the color and fill inside the aes and then use scale_*_identity to create and format the legends.
Also, I needed to add a scaling factor for severity axis since ggplot does not handle the secondary axis well.
data<-data.frame(year= 2000:2005, frequency=3:8, severity=as.integer(runif(6, 4000, 8000)))
library(ggplot2)
library(scales)
sec_plot <- ggplot(data, aes(x = year)) +
geom_col(aes(y = frequency, fill = "orange"), alpha = 0.6) +
geom_line(aes(y = severity/1000, color = "black")) +
scale_fill_identity(guide = "legend", label="Claim frequency (Number of paid claims per 100 Insured exposure)", name=NULL) +
scale_color_identity(guide = "legend", label="Claim Severity (Average insurance payment per claim)", name=NULL) +
theme(legend.position = "bottom") +
scale_y_continuous(sec.axis =sec_axis( ~ . *1, labels = label_dollar(scale=1000), name="Severity") ) + #formats the 2nd axis
guides(fill = guide_legend(order = 1), color = guide_legend(order = 2)) #control which scale plots first
sec_plot
Please consider the following:
I want to plot a step-wise curve (using geom_step()) and some smooth lines (using geom_line()) in one graph using ggplot2.
I manage to create a graph but the labels are wrong and cannot be corrected using scale_color_discrete().
Desired outcome: Based on the data (see below), line "hello" is the upper line, followed by "foo" and "bar", but the labels are not correct. In addition, I also need a label for the, now missing, geom_step()curve.
Question: What am I doing wrong?
Reproducible example:
library(ggplot2)
# Data
db <- data.frame(time = 0:100,
step = 1-pexp(0:100, rate = 1),
foo = 1-pexp(0:100, rate = 0.4),
bar = 1-pexp(0:100, rate = 0.5),
hello = 1-pexp(0:100, rate = 0.1)
)
# Plotted with wrong labels (automatically)
ggplot(data = db, aes(x = time, y = step)) +
geom_step(show.legend = T) +
geom_line(aes(x = time, y = foo, col = "red")) +
geom_line(aes(x = time, y = bar, col = "blue")) +
geom_line(aes(x = time, y = hello, col = "green"))
Looking at the labels, one can already see that the description of the color and the color of the line do not match.
# Still wrong labels
ggplot(data = db, aes(x = time, y = step)) +
geom_step(show.legend = T) +
geom_line(aes(x = time, y = foo, col = "red")) +
geom_line(aes(x = time, y = bar, col = "blue")) +
geom_line(aes(x = time, y = hello, col = "green")) +
scale_color_discrete(name = "Dose", labels = c("foo", "bar", "hello"))
Changing the labels obviously wont help.
Created on 2019-04-15 by the reprex
package (v0.2.0).
You are specifying the color you want to have inside the aesthetics-call. This means you match the color to the label "red" and not use the color "red".
You can fix this for example like this:
p <- ggplot(data = db, aes(x = time, y = step)) +
geom_step(aes(color = "step")) +
geom_line(aes(y = foo, color = "foo")) +
geom_line(aes(y = bar, color = "bar")) +
geom_line(aes(y = hello, color = "hello"))
p
Note that I dropped the x = time as this is inherited from the ggplot-call in each step. If you want to change the color for each of the lines, you should now use for example scale_color_manual like the following:
p +
scale_color_manual(name = "Dose",
values = c("step" = "black", "foo" = "red",
"bar" = "blue", "hello" = "green"))
Another option would be to transform you data to the long format:
library(tidyr)
library(dplyr)
new_db <- gather(db, type, value, -time)
ggplot(data = filter(new_db, type != "step"), aes(x = time, y = value, color = type)) +
geom_line() +
geom_step(data = filter(new_db, type == "step"))
I am plotting points over a heat map produced in ggplot2. delta is a data frame containing points to be plotted over heat map. The variable plt stores the ggplot image.
The heat map is produced by the code from this link (could not post here because of text limitation). Also, the reproducible code for all required data frames is in the link.
https://justpaste.it/65iu7
Now to superimpose points over the heat map, I used the code below:
plt0 <- plt + geom_point(data = delta, aes(x = dP/100, y = dT, z = NULL, color = rcp, shape = future))
plt0
It gives error:
Error: Continuous value supplied to discrete scale.
If I remove color = future from the above code, it works. But I need to have color coded points as this code produces:
ggplot()+geom_point(data = delta, aes(x = dP/100, y = dT, z = NULL, color = rcp, shape = future))
What is producing this error and how can I solve it?
Is it ok like this?
plt <- ggplot() + geom_tile(data=new.data, aes(x = hh/100, y = tt, fill=W)) +
geom_contour(data=new.data, bins = 10,
aes(x = hh/100, y = tt, #color = ..level..,
z = floor(W)),
show.legend = FALSE) +
ylab("Change in temperature in degree Celsius") +
xlab("percentage change in precipitation") +
scale_fill_gradientn(name = "W (in m3/year)",
values = scales::rescale(quantile(new.data$W)),
limits = c(min(new.data$W),max(new.data$W)),
breaks = seq(round(min(new.data$W)/1000000)*1000000,
round(max(new.data$W)/1000000)*1000000,
(round(max(new.data$W)/1000000)*1000000-round(min(new.data$W)/1000000)*1000000)/3),
colors = rainbow(7), guide = "colorbar") +
scale_x_continuous(breaks = seq(-0.3,0.3, 0.1), label = scales::percent) +
scale_y_continuous(breaks = seq(-1, 6, 1)) +
ggtitle("Variation of average annual sediment production with \n temperature and precipitation")+
guides(fill = guide_colorbar(barwidth = 0.5, barheight = 10))
plt
plt +
geom_point(data = delta, aes(x = dP/100, y = dT,
color = rcp, shape = future))
I did not change the code except for the first line. Instead of :
plt<-ggplot(new.data, aes(x = hh/100, y = tt, z = floor(W))) + geom_tile(aes(fill = W)) + ...
Used
plt<-ggplot()+ geom_tile(new.data, aes(x = hh/100, y = tt, fill = W)) + ...
This is to ascertain that we call empty ggplot and then add geom_tile with new.data and since the ggplot has not been assigned any data as default, we can later on add delta for geom_point. The output is as follows:
Example data frame (if there's a better/more idiomatic way to do this, let me know):
n <- 10
group <- rep(c("A","B","C"),each = n)
x <- rep(seq(0,1,length = n),3)
y <- ifelse(group == "A",1+x,ifelse(group == "B",2+2*x,3+3*x))
df <- data.frame(group,x,y)
xd <- 0.5
des <- data.frame(xd)
I want to plot create point-line plots for the data in df, add a vertical curve at the x location indicated by xd, and get readable legends for both. I tried the following:
p <- ggplot(data = df, aes(x = x, y = y, color = group)) + geom_point() + geom_line(aes(linetype=group))
p <- p + geom_vline(data = des, aes(xintercept = xd), color = "blue")
p
Not quite what I had in mind, there's no legend for the vertical line.
A small modification (I don't understand why geom_vline is one of the few geometries with a show.legend parameter, which moreover defaults to FALSE!):
p <- ggplot(data = df, aes(x = x, y = y, color = group)) + geom_point() + geom_line(aes(linetype=group))
p <- p + geom_vline(data = des, aes(xintercept = xd), color = "blue", show.legend = TRUE)
p
At least now the vertical bar is showing in the legend, but I don't want it to go in the same "category" (?) as group. I would like another legend entry, titled Design, and containing only the vertical line. How can I achieve this?
A possible approach is to add an extra dummy aesthetic like fill =, which we'll subsequently use to create the second legend in combination with scale_fill_manual() :
ggplot(data = df, aes(x = x, y = y, color = group)) +
geom_point() +
geom_line(aes(linetype=group), show.legend = TRUE) +
geom_vline(data = des,
aes(xintercept = xd, fill = "Vertical Line"), # add dummy fill
colour = "blue") +
scale_fill_manual(values = 1, "Design", # customize second legend
guide = guide_legend(override.aes = list(colour = c("blue"))))
I have the following ggplot graph with circles representing the observed data and the crosses the mean for each treatment :
d <- data.frame(Number = rnorm(12,100,20),
Treatment = rep(c("A","B","C", "D"), each = 3))
av <- aggregate(d["Number"], d["Treatment"], mean)
ggplot(data = d, aes(y = Number, x = Treatment)) +
geom_point(shape = 1, size = 6, color = "grey50") +
geom_point(data=av, shape = 4) +
theme_bw()
I would like to add a legend with the exact same symbols on top of the graphs but I'm a bit lost... I use aes to force the creation of legend and then try to modify it with manual scales but the result is not convincing. I would like to have one grey circle of size 6. That sounds also quite complicated for such a basic thing ... There is probably an easyier solution.
ggplot(data = d, aes(y = Number, x = Treatment)) +
geom_point(aes(shape = "1", size = "6", color = "grey50")) +
geom_point(data=av, aes(shape = "4")) +
theme_bw() +
scale_shape_manual(name = "", values = c(1,4), labels = c("observed values", "mean")) +
scale_size_manual(name = "", values = c(6,1), labels = c("observed values", "mean")) +
scale_color_manual(name = "", values = c("grey50","black"),
labels = c("observed values", "mean")) +
theme(legend.position = "top",
legend.key = element_rect(color = NA))
http://imagizer.imageshack.us/v2/320x240q90/842/4pgj.png
The ggplot2 way would be combining everything into a single data.frame like this:
av$Aggregated <- "mean"
d$Aggregated <- "observed value"
d <- rbind(d, av)
ggplot(data = d, aes(y = Number, x = Treatment,
shape=Aggregated, size=Aggregated, colour=Aggregated)) +
geom_point()
And than customize using manual scales and themes.