I want to add a textbox of 10 separate, stacked lines outside of my plot area in ggplot. My text is: t = c("a=1", "b=2", "c=3", ... , "j=10") but these labels are independent of the data.frame that I made my original ggplot. How can I add 10 lines outside of the plot area?
For example, I want to add a textbox around my vector t on the right of the following plot:
df = data.frame(y=rnorm(300), test=rep(c(1,2,3),each=100))
t = c("a=1", "b=2", "c=3", "d=4", "e=5", "f=6", "g=7", "h=8", "i=0", "j=10")
p <- ggplot(df, aes(x=factor(test), y=y))
p <- p + geom_violin() + geom_jitter(height=0, width=0.1)
p <- p + theme(legend.title=element_blank(), plot.margin=unit(c(0.1, 3, 0.1, 0.1), "cm"))
p
try
library(gridExtra)
grid.arrange(p, right = tableGrob(matrix(t,ncol=1),
theme = ttheme_minimal(padding = unit(c(3,1),"line"))))
You can create a geom_text layer using the label values in t in order to get the labels printed as a legend. But we set alpha=0 in geom_text so that these labels won't be included in the plot, and we use legend.key=element_blank() and override.aes(list(size=0)) to get the "legend" labels (the t values) printed without the meaningless legend key.
p +
geom_text(data = data.frame(t, test=NA, y=NA), aes(label=t, colour=t), alpha=0, x=1, y=1) +
theme(legend.key=element_blank(),
legend.margin=margin(l=-10)) +
guides(colour=guide_legend(override.aes=list(size=0)))
Related
I want to add a new legend to my plot. But I hope the legend is all customized.
I add the label for every point by geom_text_repel.
The new legend describes the of character of the labels.
You can create a legend by creating "dummy" data that contains the legend key labels. You would then "plot" the dummy data in order to generate the legend, but use blank symbols so that nothing actually gets plotted.
library(ggplot2)
theme_set(theme_classic())
# Fake data for plotting
set.seed(2)
val = sapply(sample(1:4,30,replace=TRUE), function(x) paste(sort(sample(c('c','u','x','t'), x)), collapse=""))
dat = data.frame(x=runif(30), y=runif(30), val)
# Dummy data for creating the legend
leg = data.frame(x1=rep(0,4), y1=rep(0,4), ll = c("c: coor","u: url","x: xss","t: text"))
ggplot(data=dat, aes(x,y)) +
geom_text(aes(label=val)) +
geom_point(data=leg, aes(x1, y1, colour=ll)) +
theme(legend.key.size=unit(15,"pt"),
legend.title=element_blank(),
legend.margin=margin(l=0),
legend.text=element_text(size=12)) +
scale_colour_manual(values=rep("#00000000", 4))
You could also use geom_text to place the "legend" annotations directly:
leg = data.frame(ll = sort(c("c: coor","u: url","x: xss","t: text")))
leg$y = seq(mean(dat$y) + 0.05*diff(range(dat$y)),
mean(dat$y) - 0.05*diff(range(dat$y)),
length=4)
leg$x = 1.07 * max(dat$x)
ggplot(data=dat, aes(x,y)) +
geom_text(aes(label=val)) +
geom_text(dat=leg, aes(label=ll), hjust=0, colour="red") +
annotate(xmin=1.05 * max(dat$x), xmax=1.18 * max(dat$x), ymin=0.95*min(leg$y), ymax=1.04*max(leg$y),
geom="rect", fill=NA, colour="black") +
scale_x_continuous(limits=c(min(dat$x), 1.18*max(dat$x)))
This question is motivated by a previous post illustrating various ways to change how axes scales are plotted in a ggplot figure, from the default exponential notation to the full integer value (when ones axes values are very large). While I am able to convert the axes scales from exponential notation to full values, I am unclear how one would achieve the same goal for the values appearing in the legend.
While I understand that one can manually change the length of the legend scale with "scale_color..." or "scale_fill..." followed by the "limits" argument, this does not appear to be a solution to getting my legend values to show "6000000000" rather than "6e+09" (or "0" rather than "0e+00" for that matter).
The following example should suffice. My hope is someone can point out how to implement the 'scales' package to apply for legend scales rather than axes scales.
Thanks very much.
library(ggplot2)
library(scales)
Data <- data.frame(
pi = c(2,71,828,1828,45904,523536,2874713,52662497,757247093,6999595749),
e = c(3,14,159,2653,58979,311599,7963468,54418516,1590576171, 99),
face = 1:10)
p <- ggplot(data = Data, aes(x=face, y=e, colour = pi))
myplot <- p + geom_point() +
scale_y_continuous(labels = comma) +
scale_color_gradientn(colours = rainbow(2), limits=c(0,7000000000))
myplot
Use the Comma formatter in scale_color_gradientn by setting labels = comma e.g.:
p <- ggplot(data = Data, aes(x=face, y=e, colour = pi))
myplot <- p + geom_point() +
scale_y_continuous(labels = comma) +
scale_color_gradientn(colours = rainbow(2), limits=c(0,7000000000), labels = comma)
myplot
I want to produce a barplot overlayed with dots where both have separate legends. Also, I want to choose the color of the bars and the size of the dots using the arguments outside aes(). As both are not mapped, no legend is produced.
1) How can I add a legend manually for both fill and size?
library(ggplot2)
d <- data.frame(group = 1:3,
prop = 1:3 )
ggplot(d, aes(x=group, y=prop)) +
geom_bar(stat="identity", fill="red") +
geom_point(size=5)
This is what I came up with: I used dummy mappings and modified the legend according to my needs afterwards. But this approach appears clumsy to me.
2) Is there a manual way to say: Add a legend with this title, these shapes, these colors etc.?
d <- data.frame(dummy1="d1",
dummy2="d2",
group = 1:3,
prop = 1:3 )
ggplot(d, aes(x=group, y=prop, fill=dummy1, size=dummy2)) +
geom_bar(stat="identity", fill="red") +
geom_point(size=5) +
scale_fill_discrete(name="fill legend", label="fill label") +
scale_size_discrete(name="size legend", label="size label")
Above I mapped fill to dummy1. So I would expect scale_fill_discrete to alter this legend. But it appears to modify the size legend instead.
3) I am not sure what went wrong here. Any ideas?
I'm not sure why you say "Also, I want to choose the color of the bars and the size of the dots using the arguments outside aes()". Is it something you're trying to do or is it something that you have to do given how ggplot works?
If it's the latter, one solution is as under -
library(ggplot2)
d <- data.frame(group = 1:3,
prop = 1:3 )
ggplot(d, aes(x=group, y=prop)) +
geom_bar(stat="identity",aes( fill="label")) +
geom_point(aes(size='labelsize')) +
scale_fill_manual(breaks = 'label', values = 'red')+
scale_size_manual(breaks = 'labelsize', values = 5)
Is there any way to line up the points of a line plot with the bars of a bar graph using ggplot when they have the same x-axis? Here is the sample data I'm trying to do it with.
library(ggplot2)
library(gridExtra)
data=data.frame(x=rep(1:27, each=5), y = rep(1:5, times = 27))
yes <- ggplot(data, aes(x = x, y = y))
yes <- yes + geom_point() + geom_line()
other_data = data.frame(x = 1:27, y = 50:76 )
no <- ggplot(other_data, aes(x=x, y=y))
no <- no + geom_bar(stat = "identity")
grid.arrange(no, yes)
Here is the output:
The first point of the line plot is to the left of the first bar, and the last point of the line plot is to the right of the last bar.
Thank you for your time.
Extending #Stibu's post a little: To align the plots, use gtable (Or see answers to your earlier question)
library(ggplot2)
library(gtable)
data=data.frame(x=rep(1:27, each=5), y = rep(1:5, times = 27))
yes <- ggplot(data, aes(x = x, y = y))
yes <- yes + geom_point() + geom_line() +
scale_x_continuous(limits = c(0,28), expand = c(0,0))
other_data = data.frame(x = 1:27, y = 50:76 )
no <- ggplot(other_data, aes(x=x, y=y))
no <- no + geom_bar(stat = "identity") +
scale_x_continuous(limits = c(0,28), expand = c(0,0))
gYes = ggplotGrob(yes) # get the ggplot grobs
gNo = ggplotGrob(no)
plot(rbind(gNo, gYes, size = "first")) # Arrange and plot the grobs
Edit To change heights of plots:
g = rbind(gNo, gYes, size = "first") # Combine the plots
panels <- g$layout$t[grepl("panel", g$layout$name)] # Get the positions for plot panels
g$heights[panels] <- unit(c(0.7, 0.3), "null") # Replace heights with your relative heights
plot(g)
I can think of (at least) two ways to align the x-axes in the two plots:
The two axis do not align because in the bar plot, the geoms cover the x-axis from 0.5 to 27.5, while in the other plot, the data only ranges from 1 to 27. The reason is that the bars have a width and the points don't. You can force the axex to align by explicitly specifying an x-axis range. Using the definitions from your plot, this can be achieved by
yes <- yes + scale_x_continuous(limits=c(0,28))
no <- no + scale_x_continuous(limits=c(0,28))
grid.arrange(no, yes)
limits sets the range of the x-axis. Note, though, that the alginment is still not quite perfect. The y-axis labels take up a little more space in the upper plot, because the numbers have two digits. The plot looks as follows:
The other solution is a bit more complicated but it has the advantage that the x-axis is drawn only once and that ggplot makes sure that the alignment is perfect. It makes use of faceting and the trick described in this answer. First, the data must be combined into a single data frame by
all <- rbind(data.frame(other_data,type="other"),data.frame(data,type="data"))
and then the plot can be created as follows:
ggplot(all,aes(x=x,y=y)) + facet_grid(type~.,scales = "free_y") +
geom_bar(data=subset(all,type=="other"),stat="identity") +
geom_point(data=subset(all,type=="data")) +
geom_line(data=subset(all,type=="data"))
The trick is to let the facets be constructed by the variable type which was used before to label the two data sets. But then each geom only gets the subset of the data that should be drawn with that specific geom. In facet_grid, I also used scales = "free_y" because the two y-axes should be independent. This plot looks as follows:
You can change the labels of the facets by giving other names when you define the data frame all. If you want to remove them alltogether, then add the following to your plot:
+ theme(strip.background = element_blank(), strip.text = element_blank())
I'm using ggplot2 to just count and summarize the number of occurrences of each mode in my data frame. testdata$V5 is a factor with 4 different modes. Every line in testdata has an entry for mode and I want to count them.
p <- ggplot(testdata,aes(V5))
p = p + geom_histogram()
show(p)
This code produces the following plot:
I am now trying to show text labels on top of each bar plot that show the count but I can't quite understand how to achieve that using stat_summary. How can I produce a text label at the top of each x value bar showing the count?
I tried
p <- ggplot(testdata,aes(V5))
p = p + geom_histogram()
p = p + stat_summary(fun.data=count, geom="text", size=20, color="red") #<-- no effect
show(p)
but it doesn't draw anything.
You can use a "hidden" variable ..count.. in conjunction with geom_text:
p +
geom_histogram() +
stat_bin(aes(label=..count..), geom="text", position="identity", size=20, color="red")
geom_text also has hjust and vjust parameters that may be helpful.