I face a problem with R (and its well known rigor in dealing with objects...) : I wrote a custom function to plot dotplots from ggplots and add a custom p value with brackets. The problem is not the plot (it works well...) but dealing with objects and functions : I cannot use an object created inside the function. Some code to explain :
pval.label <- function(p)
{
if (p < 0.001) { return("p<0.001") }
else { return(paste0("p = ", round(p, digits = 2))) }
}
dot_plot <- function(data, var, endpoint, title, ylab)
{
endpoint = deparse(substitute(endpoint))
var = deparse(substitute(var))
df = data.frame(var = data[[var]], endpoint = data[[endpoint]])
pvalue = compare_means(data = df, formula = var ~ endpoint)
pvalue <- pvalue %>% mutate(y.position = 120*(max(df$var)/100))
plot =
ggplot(df, aes(x=endpoint, y=var)) +
labs(title = title, y = ylab, x="") +
geom_dotplot(binaxis='y', stackdir='center', stackratio=1.7, binwidth = .8, show.legend = F,
aes(fill = endpoint, color = endpoint)) +
stat_summary(fun=median, geom="crossbar", lwd=.5, width=.7, col="black", show.legend=F) +
scale_fill_manual(values=c("#2d419b", "#ee2025")) +
scale_color_manual(values=c("#2d419b", "#ee2025")) +
theme_classic() +
theme(text = element_text(family = "sans", face = "bold"),
plot.title = element_text(size = 14, hjust = .5, lineheight = 1.5),
axis.text = element_text(size = 12, face = "bold", colour = "black"),
axis.title = element_text(size = 14, face = "bold", colour = "black"),
axis.line = element_line(size = 1),
axis.ticks = element_line(size = 1), axis.ticks.length = unit(5, "pt")) +
stat_pvalue_manual(pvalue, label = "{pval.label(pvalue$p)}", bracket.size = 1, size = 4)
plot
}
The problem is with this line :
stat_pvalue_manual(pvalue, label = "{pval.label(pvalue$p)}", bracket.size = 1, size = 4)
It says the object "pvalue" is not found. But, if I create this object outside the function and have it in R environment, it works well !!
How to explain that ? And how to deal with it ?
Thanks,
Olivier
Related
So I've been trying to work with a data.frame and a shapefile I've been using the below code:
Jul_Col_map <-
ggplot(data = Jul_Data, aes(x = Long_DD, y = Lat_DD, color = Coliform)) +
geom_point(size = 4) +
geom_sf(aes(Cave_initial), size = 1) +
scale_color_gradient(low = "blue", high = "red") +
labs(x = "",
y = "",
color = "Coliform (cfu/100mL)") +
guides(color = guide_colourbar(barwidth = 0.5, barheight = 10)) +
theme_classic() +
theme(axis.text.x = element_text(face = "bold", color = "black", size = 12), axis.text.y =
element_text(face = "bold", color = "black", size = 12), axis.title.x = element_text(face =
"bold", color = "black", size = 16), axis.title.y = element_text(face = "bold", color = "black",
size = 16))
Jul_Col_map
But I always get the error
Error in FUN(X[[i]], ...) : object 'Long_DD' not found
I have properly uploaded the data set and converted it to a sf using st_as_sf and when I run selected code everything works fine until I actually want to show the map.
I have the following bubble plot that shows the abundance percentage of microbes across different samples. However, I want to remove the tick labels called "Archaea" and "Other taxa" (located at either ends of the bubble plot) since the labels for both can be placed in the x-axis strip text instead. I used the following code to produce the plot:
ggplot(En.TaxMisc.NoC.RelAb.filtered.tidy$CombinedMisc,
aes(x = factor(Taxonomy, levels = En.TaxMisc.order$Taxonomy),
y = SampleSource, size = RelAb)) +
geom_point(colour = '#abd9e9') +
facet_grid(SampleType ~ Level,
labeller = labeller(SampleType = SampleType.NoC.labels),
scale = 'free', space = 'free') +
scale_x_discrete(name = NULL) +
scale_y_discrete(position = 'left', name = NULL) +
scale_size_continuous(name = str_wrap('Relative abundances (%)', width = 10),
breaks = c(1:8), range = c(0.75, 20)) +
guides(size = guide_legend(nrow = 1)) +
theme(legend.position = 'bottom',
legend.background = element_rect(colour = 'grey70'),
legend.title = element_text(size = 8, hjust = 1),
legend.text = element_text(size = 7, hjust = 0),
legend.spacing.x = unit(2.5, 'mm'),
legend.box = 'horizontal',
strip.background = element_rect(colour = 'grey55'),
strip.text.x = element_text(size = 8),
strip.text.y = element_text(size = 8),
axis.text.x.bottom = element_text(angle = 90, hjust = 1,
vjust = 0.3, size = 8),
axis.text.y.left = element_text(size = 8),
axis.ticks = element_blank(),
panel.grid.major.x = element_line(linetype = 1),
panel.border = element_rect(linetype = 1, fill = NA),
panel.background = element_blank())
I had tried to use scale_x_discrete(labels = c("Archaea" = NULL, "Other taxa" = NULL) but this resulted in all the tick labels being removed. I had also looked into using the rremove() function and the axis_ticks theme components, but neither appear to possess arguments for specifying tick labels.
I'd appreciate suggestions or advice anyone can give me!
There's a fair bit of extraneous detail in the question, but if you're just looking to remove (or customize!) tick labels, all you need is to add a labels argument to scale_x_discrete.
Self-contained example:
library(ggplot2)
ds = data.frame(
xVar = as.factor(rep(LETTERS[1:5],10)),
y = rnorm(50)
)
my_custom_labels = c("","level B","level C","level D!","")
ggplot(data = ds) +
geom_point(aes(x = xVar,y = y)) +
scale_x_discrete(labels = my_custom_labels)
I have produced some nice plots with the plotLearnerPrediction function of the MLR package. I was able to make some adjustments to the returned ggplot (see my code below). But I am not sure how to make the last adjustment. Namely, I want to change the coloring of the data points based on labels (groups in example plot).
My last plot (with black data points)
Another produced plot (overlapping data points)
This is the last version of my code (normally part of a for loop):
plot <- plotLearnerPrediction(learner = learner_name, task = tasks[[i]], cv = 0,
pointsize = 1.5, gridsize = 500) +
ggtitle(trimws(sprintf("Predictions %s %s", meta$name[i], meta$nr[i])),
subtitle = sprintf("DR = %s, ML = %s, CV = LOO, ACC = %.2f", meta$type[i],
toupper(strsplit(learner_name, "classif.")[[1]][2]), acc[[i]])) +
xlab(sprintf("%s 1", lab)) +
ylab(sprintf("%s 2", lab)) +
scale_fill_manual(values = colors) +
theme(plot.title = element_text(size = 18, face = "bold"),
plot.subtitle = element_text(size = 12, face = "bold", colour = "grey40"),
axis.text.x = element_text(vjust = 0.5, hjust = 1),
axis.text = element_text(size = 14, face = "bold"),
axis.title.x = element_text(vjust = 0.5),
axis.title = element_text(size = 16, face = "bold"),
#panel.grid.minor = element_line(colour = "grey80"),
axis.line.x = element_line(color = "black", size = 1),
axis.line.y = element_line(color = "black", size = 1),
panel.grid.major = element_line(colour = "grey80"),
panel.background = element_rect(fill = "white"),
legend.justification = "top",
legend.margin = margin(l = 0),
legend.title = element_blank(),
legend.text = element_text(size = 14))
Below is a part of the source code of the plotLearnerPrediction function. I want to overrule geom_point(colour = "black"). Adding simply geom_point(colour = "pink") to my code will not color data points, but the whole plot. Is there a solution to overrule that code with a vector of colors? Possibly a change in the aes() is also needed to change colors based on groups.
else if (taskdim == 2L) {
p = ggplot(mapping = aes_string(x = x1n, y = x2n))
p = p + geom_tile(data = grid, mapping = aes_string(fill = target))
p = p + scale_fill_gradient2(low = bg.cols[1L], mid = bg.cols[2L],
high = bg.cols[3L], space = "Lab")
p = p + geom_point(data = data, mapping = aes_string(x = x1n,
y = x2n, colour = target), size = pointsize)
p = p + geom_point(data = data, mapping = aes_string(x = x1n,
y = x2n), size = pointsize, colour = "black",
shape = 1)
p = p + scale_colour_gradient2(low = bg.cols[1L],
mid = bg.cols[2L], high = bg.cols[3L], space = "Lab")
p = p + guides(colour = FALSE)
}
You can always hack into gg objects. The following works for ggplot2 2.2.1 and adds a manual alpha value to all geom_point layers.
library(mlr)
library(ggplot2)
g = plotLearnerPrediction(makeLearner("classif.qda"), iris.task)
ids.geom.point = which(sapply(g$layers, function(z) class(z$geom)[[1]]) == "GeomPoint")
for(i in ids.geom.point) {
g$layers[[i]]$aes_params$alpha = 0.1
}
g
The plotLearnerPrediction() function returns the ggplot plot object, which allows for some level of customization without having to modify the source code. In your particular case, you can use scale_fill_manual() to set custom fill colors:
library(mlr)
g = plotLearnerPrediction(makeLearner("classif.randomForest"), iris.task)
g + scale_fill_manual(values = c("yellow", "orange", "red"))
I am having trouble printing a plot from ggplot to plotly, and maintaining a good text position.
Data example:
library(ggplot2)
library(plotly)
library(dplyr)
library(reshape2)
#mock data
df1 <- data.frame(
Gruppering2 = factor(c("Erhverv Erhverv Salg","Erhverv Erhverv Salg","Erhverv Erhverv Salg")),
periode = factor(c("Denne maaned","Denne uge", "I gaard")),
Answer_rate = c(0.01,0.4,0.7),
SVL = c(0.40,0.43,0.67),
over_180 = c(0.5,0.7,0.3)
)
#color
plotCol <- c( rgb(44,121,91, maxColorValue = 255), rgb(139,0,0, maxColorValue = 255),rgb(0,0,139, maxColorValue = 255))
#plot code
dfpct <- melt(df1[,c(2,3,4,5)], id.vars = "periode",
measure.vars = c( "Answer_rate","SVL", "over_180"),
variable.name = "P", value.name = "value")
dfpct <- na.omit(dfpct)
pct <- ggplot(dfpct, aes(x = periode, y = value, fill = P, group = P, width = 0.6)) +
geom_bar(stat = "identity", position="dodge", colour = "black", width = 0.7, show.legend = FALSE) +
labs(x = NULL, y = "Calls") +
#ggtitle("Forecast Error") +
theme_bw() +
theme(panel.grid.major = element_blank(),
plot.title = element_text(size = rel(1.2), face = "bold", vjust = 1.5),
axis.title = element_text(face = "bold"),
axis.text = element_text(),
legend.position = "bottom",
legend.direction = "vertical",
legend.key.width = unit(2, "lines"),
legend.key.height = unit(0.5, "lines"),
legend.title = element_blank()) +
geom_text(aes(label=paste(value*100,"%",sep="")), position = position_dodge(width=0.6), vjust = -0.5 ) +
scale_fill_manual(values = plotCol)
pct # the is perfectly located above
ggplotly(pct, textposition = 'top center') # text crosses over the bars
As you can see - the ggplot works excellent - however when I convert to plotly, the text is moved. I've tried playing around with various settings in both ggplot and plotly, but no luck yet.
Looks like vjust is not recognized but maybe on the roadmap. From GitHub:
# convert ggplot2::element_text() to plotly annotation
make_label <- function(txt = "", x, y, el = ggplot2::element_text(), ...) {
if (is_blank(el) || is.null(txt) || nchar(txt) == 0 || length(txt) == 0) {
return(NULL)
}
angle <- el$angle %||% 0
list(list(
text = txt,
x = x,
y = y,
showarrow = FALSE,
# TODO: hjust/vjust?
ax = 0,
ay = 0,
font = text2font(el),
xref = "paper",
yref = "paper",
textangle = -angle,
...
))
}
Easiest approach might be to assign the y value in geom_text, but you'll lose some scaling in the height.
pct <- ggplot(dfpct, aes(x = periode, y = value, fill = P, group = P, width = 0.6)) +
geom_bar(stat = "identity", position="dodge", colour = "black", width = 0.7, show.legend = FALSE) +
labs(x = NULL, y = "Calls") +
theme_bw() +
theme(panel.grid.major = element_blank(),
plot.title = element_text(size = rel(1.2), face = "bold", vjust = 1.5),
axis.title = element_text(face = "bold"),
axis.text = element_text(),
legend.position = "bottom",
legend.direction = "vertical",
legend.key.width = unit(2, "lines"),
legend.key.height = unit(0.5, "lines"),
legend.title = element_blank()) +
geom_text(aes(label=paste(value*100,"%",sep=""), y = value+0.01), position = position_dodge(width = 0.6)) +
scale_fill_manual(values = plotCol)
ggplotly(pct)
Alternatively, if you know the dimensions of the final output, you could edit the components of a plotly_build object:
gg <- plotly_build(pct)
gg$data[[4]]$y <- gg$data[[4]]$y+0.006
gg$data[[5]]$y <- gg$data[[5]]$y+0.006
gg$data[[6]]$y <- gg$data[[6]]$y+0.006
I had the same issue, I solved it by adding a value to the y axis, but in order to avoid the scaling issue, I added a percentage of the minimum. You can adjust it depending upon your data itself. I hope it helps:
geom_text(aes(label=paste(value*100,"%",sep=""), y = value+0.1*min(value), position = position_dodge(width = 0.6))
I have used the following example for my question:
http://www.cmap.polytechnique.fr/~lepennec/R/Radar/RadarAndParallelPlots.html
mtcarsscaled <- as.data.frame(lapply(mtcars, ggplot2:::rescale01))
mtcarsscaled$model <- rownames(mtcars)
mtcarsmelted <- reshape2::melt(mtcarsscaled)
coord_radar <- function (theta = "x", start = 0, direction = 1)
{
theta <- match.arg(theta, c("x", "y"))
r <- if (theta == "x")
"y"
else "x"
ggproto("CordRadar", CoordPolar, theta = theta, r = r, start = start,
direction = sign(direction),
is_linear = function(coord) TRUE)
}
plot <- ggplot(mtcarsmelted, aes(x = variable, y = value)) +
geom_polygon(aes(group = model, color = model), fill = NA, size = 2, show.legend = FALSE) +
geom_line(aes(group = model, color = model), size = 2) +
theme(strip.text.x = element_text(size = rel(0.8)),
axis.text.x = element_text(size = rel(0.8)),
axis.ticks.y = element_blank(),
axis.text.y = element_blank()) +
xlab("") + ylab("") +
guides(color = guide_legend(ncol=2)) +
coord_radar()
print(plot)
How can I change the color of the outermost line of the plot/grid (the line underneath the y-labels)?
Any help is much appreciated!
That line is unfortunately controlled with the grid.major argument, but is not an explicit break. The only way I've found to do this is by cancelling the rest of the breaks like so:
ggplot(mtcarsmelted, aes(x = variable, y = value)) +
geom_polygon(aes(group = model, color = model), fill = NA, size = 2, show.legend = FALSE) +
geom_line(aes(group = model, color = model), size = 2) +
theme(strip.text.x = element_text(size = rel(0.8)),
axis.text.x = element_text(size = rel(0.8)),
axis.ticks.y = element_blank(),
axis.text.y = element_blank(),
panel.grid.major.y = element_line(colour = "blue", size = 0.2), #changed
xlab("") + ylab("") +
guides(color = guide_legend(ncol=2)) +
scale_y_continuous(breaks = NULL) + #changed
coord_radar()
Which gives:
Unfortunately you lose the ability to have a y grid (which to be honest if you are not labeling in a polar grid is not that important anyway). You can alter the colour with the colour argument in element_line