I am quite new to ggplot2, so forgive me if this post is too stupid.
I used the following code to plot the data, but I am not able to get the style that I need for publication.
In the output, I need:
a legend. In my data case, there is nothing after opts(legend.position="top") I have no idea why. And I also would like to split the legend into 3 columns like columns=3 in auto.key of lattice
Colorize the bars using grey system (eg, fill=c("white","grey20","grey70"))according to factor pl, but it seems that I cannot change the style with scale_colour_manual
turn around the labels on the x-axis into horizontal.
maybe a y-axis? But,do you think it is necessary?
BTW, I have no idea how to prepare a figure for publication, so, any suggestion is very welcome!
library(ggplot2)
wt<-gl(3,4,108,labels=c("W30","W60","W90"))
pl<-gl(3,12,108,labels=c("P0","P1","P2"))
gp<-gl(3,36,108,labels=c("A","B","C"))
dat<-cbind(A=runif(108),B=runif(108,min=1,max=10),C=runif(108,min=100,max=200),D=runif(108,min=1000,max=1500))
dat.df<-data.frame(wt,pl,gp,dat)
dat.m<-melt(dat.df)
ggplot(dat.m,aes(x=wt,y=value,group=pl,facet=gp,fill=pl))+
stat_summary(fun.y=mean,geom="bar",size=2,position="dodge")+
stat_summary(fun.ymin=function(x)(mean(x)-sd(x)/sqrt(length(x))),geom="errorbar",
fun.ymax=function(x)(mean(x)+sd(x)/sqrt(length(x))),position="dodge")+
facet_grid(variable~facet,scale="free_y")+ opts(legend.position="top")+
scale_colour_manual(values = c("red", "blue", "green"))
Here are some pointers:
To get a horizontal legend, use opts(legend.direction="horizontal")
To change the fill of the bars, you have to specify scale_fill_manual(values=c("white", "grey20", "grey70")). In your example, you have correctly mapped fill to pl. The only missing step is to map the manual scale to fill, rather than colour. Colour generally refers to the outline of the bar, and fill refers to the inside of the bar.
To rotate the angle of axis text, use opts(axis.text.x = theme_text(angle=45)). The default orientation is horizontal, so I use 45 degrees for illustration.
I don't know what you mean by "maybe a y-axis". Perhaps you don't want to display the y-axis, in which case you can suppress it by opts(axis.title.y = theme_blank())
Note that your example was not reproducible, so I had to invent some data. You can make it easier for us to respond if you ensure your example is reproducible:
There is no data for year
There is a reference to trt in your data.frame
You set up data for grp but then refer to it as gp
My code:
dat.df <- data.frame(
gp = gl(3, 36, 108, labels=c("A", "B", "C")),
yr = sample(2000:2010, 108, replace=TRUE),
A=runif(108),
B=runif(108, min=1, max=10),
C=runif(108, min=100, max=200),
D=runif(108, min=1000, max=1500)
)
dat.m <- melt(dat.df)
ggplot(dat.m, aes(x=wt, y=value, group=pl, facet=gp, fill=pl))+
stat_summary(fun.y=mean, geom="bar", size=2, position="dodge")+
stat_summary(fun.ymin=function(x)(mean(x)-sd(x)/sqrt(length(x))), geom="errorbar",
fun.ymax=function(x)(mean(x)+sd(x)/sqrt(length(x))), position="dodge")+#, position="dodge"
facet_grid(variable~facet, scale="free_y")+
scale_fill_manual(values=c("white", "grey20", "grey70")) +
opts(
legend.position="top",
legend.direction="horizontal",
axis.text.x = theme_text(angle=45),
axis.title.y = theme_blank()
)
Related
I am trying to make a lollipop plot that includes a text 'condition' and a value associated. The issue I am having is that, because there is so much data, the labels overlap. Is there an easy fix for this?
This is my code (and my issue):
library(ggplot2)
df <- read.table(file = '24 hpi MP BP.tsv', sep = '\t', header = TRUE)
group <- df$Name
value <- df$Bgd.count
data <- data.frame(
x=group,
y=value
)
ggplot(data, aes(x=x, y=y)) +
geom_segment( aes(x=x, xend=x, y=0, yend=y), color="skyblue") +
geom_point( color="blue", size=4, alpha=0.6) +
theme_light() +
coord_flip() +
theme(
panel.grid.major.y = element_blank(),
panel.border = element_blank(),
axis.ticks.y = element_blank()
)
I am hoping to get a clear separation on the labels
Your question does not provide a reproducible example, so here a more general answer.
The problem is that you want to plot hundreds of discrete values. That is bound to yield a crowded graphic.
your options:
reduce the labels (don’t label all axis) and show only few labels .
focus only on few important data points - I think this would be my preferred approach, as you also give your “story” more justice.
Group your values and show “aggregate values” such as means/error bars
Make your graph appropriately large (change the height of the so called graphic device)
Use facets (but this will not really help with the crowding in all cases)
Shorten your labels
Make the font smaller
Last, but definitely not least, change your visualisation strategy.
So I know many people have asked similar questions but the code others have used does not seem to be working for my graph hence why I'm wondering if I have done something wrong.
I have this code:
ggplot(dfMonth)
+ geom_col(aes(x=Month, y=NumberMO), size=.7, colour="black", fill="white")
+ geom_line(aes(x=Month, y=NumberME), size=1, colour="black", group=1)
+ xlab("Month")
+ ylab("No. of birds observed")
+ theme_bw()
+ geom_point(x=Month, y=NumberME)
+ scale_colour_manual("" ,values =c("NumberME"="black"), labels=c("Expected No. of birds"))
+ theme(legend.key=element_blank(),legend.title=element_blank(), legend.box="horizontal")
+ theme(axis.title.x = element_text(margin = unit(c(5, 0, 0, 0), "mm")),
axis.title.y = element_text(margin = unit(c(0,3 , 0, 0), "mm")))
Which produces this graph:
so as you can see, the legend to show what the black line with the points mean has not been added to my graph even though I have inputted the code. No error comes up so hence why I'm lost on whats wrong. Any ideas on what i've failed to include?
Thanks
In order for ggplot to know to draw a legend, you need to include one of the aesthetics for a geom within aes(). In this case, if you want a legend to be drawn for your line, you need to include within the aes() in the geom_line() call one of the aesthetics that you have identified for the line: linetype or color works. We'll use color here.
Oh... and in the absence of OP sharing their dataset, here's a made-up example:
set.seed(1234)
dfMonth <- data.frame(
Month=month.name,
NumberMO=sample(50:380, 12),
NumberME=sample(50:380, 12)
)
Now the code to make the plot and ensure the legend is created.
p <- ggplot(dfMonth, aes(x=Month)) +
geom_col(aes(y=NumberMO), size=0.7, color="black", fill="white") +
geom_line(aes(y=NumberME, color='black'), size=1, group=1)
p
We have a legend, but there's some problems. You get the default title of the legend (which is the name of the aesthetic), and the default label (which is whatever text you put inside aes(color=.... Since we put "black" as the value there, it's applied as the label, and not the actual color. The actual color of the line is to default to the first level of the standard colorset used by ggplot2, which in this case is that light red color.
To set the color, name of the legend, and name of the label, we should specify the value. There's only one item in the legend, so there's no need to specify, but if you were to send a named vector to indicate the name for our single line explicitly, you end up with the somewhat strange-looking c('black'='black'). I also included a line break in the label name to make the look a bit better. Also, the months were running into each other, so I also changed the angle of the x axis labels.
Finally, you might notice the months were out of order. That's because default ggplot2 behavior is to factor a column of discrete values, which uses alphabetical ordering for the levels. To fix that, you specify the column as a factor before plotting with the correct levels.
dfMonth$Month <- factor(dfMonth$Month, levels=month.name)
p + scale_color_manual(
name=NULL, values=c('black'='black'),
labels='Expected No.\nof birds') +
theme(axis.text.x=element_text(angle=30, hjust=1))
I am working in a heat map for some eye tracking data. I figured out how to do the heat map and it is very compelling. This is the code:
ggplot(eyematrixCorrectMatchControl, aes(x = CURRENT_FIX_X, y =CURRENT_FIX_Y)) +
annotation_raster(image, -Inf, Inf, -Inf, Inf, interpolate = TRUE) +
stat_density2d(data= eyematrixCorrectMatchControl, aes(x = CURRENT_FIX_X, y =CURRENT_FIX_Y, fill = ..level.., alpha = ..level..), size= 10, bins= 50, geom='polygon') +
theme_bw() +scale_fill_gradient(low = "blue", high = "red") +
scale_alpha_continuous(range=c(0.01,0.25) , guide = FALSE) +
coord_cartesian(xlim= c(0,1024), ylim= c(0,768))+
scale_y_reverse() +
theme(axis.line=element_blank(),
axis.text.x=element_blank(),
axis.text.y=element_blank(),
axis.ticks=element_blank(),
axis.title.x=element_blank(),
axis.title.y=element_blank())
With this code, I obtain this image:
However, I don't understand some things. I thought that this code would give me a graph the number of fixations in a specific area (the more fixation the redder the area is). However, looking at the legend I am not sure what this graph shows. How can I obtain a graph showing the number of fixations? I would also like that the legend reflects the number of fixations, so the redder the more fixations. Any idea??
I edit to add some extra information that might be useful. In my original dataframe I also have a variable called fixation_index. I think that I have to include this variable somewhere, but not really sure.
Thanks!
Heatmap.2 offers a histogram option that correlates color with the density count. It looks like this.
I have a really simple question, which I am struggling to find the answer to. I hoped someone here might be able to help me.
An example dataframe is presented below:
a <- c(1:10)
b <- c(10:1)
df <- data.frame(a,b)
library(ggplot2)
g = ggplot(data=df) + geom_point(aes(x=a, y=b)) +
xlab("x axis")
g
I just want to learn how I change the text size of the axes titles and the axes labels.
You can change axis text and label size with arguments axis.text= and axis.title= in function theme(). If you need, for example, change only x axis title size, then use axis.title.x=.
g+theme(axis.text=element_text(size=12),
axis.title=element_text(size=14,face="bold"))
There is good examples about setting of different theme() parameters in ggplot2 page.
I think a better way to do this is to change the base_size argument. It will increase the text sizes consistently.
g + theme_grey(base_size = 22)
As seen here.
If you are creating many graphs, you could be tired of typing for each graph the lines of code controlling for the size of the titles and texts. What I typically do is creating an object (of class "theme" "gg") that defines the desired theme characteristics. You can do that at the beginning of your code.
My_Theme = theme(
axis.title.x = element_text(size = 16),
axis.text.x = element_text(size = 14),
axis.title.y = element_text(size = 16))
Next, all you will have to do is adding My_Theme to your graphs.
g + My_Theme
if you have another graph, g1, just write:
g1 + My_Theme
and so on.
To change the size of (almost) all text elements, in one place, and synchronously, rel() is quite efficient:
g+theme(text = element_text(size=rel(3.5))
You might want to tweak the number a bit, to get the optimum result. It sets both the horizontal and vertical axis labels and titles, and other text elements, on the same scale. One exception is faceted grids' titles which must be manually set to the same value, for example if both x and y facets are used in a graph:
theme(text = element_text(size=rel(3.5)),
strip.text.x = element_text(size=rel(3.5)),
strip.text.y = element_text(size=rel(3.5)))
I am trying to plot a heat map with ggplot2 and I would like to resize the colorbar and increase the font.
Here is the relevant part of the code:
g <- ggplot(data=melt.m)
g2 <- g+geom_rect(aes(xmin=colInd-1, xmax=colInd,
ymin=rowInd-1, ymax=rowInd, fill=value))
g2 <- g2+scale_x_continuous('beta', breaks=c(1, ceiling(cols/2), rows)-0.5,
labels=c(1,ceiling(cols/2), rows))
g2 <- g2+scale_y_continuous('alpha', breaks=c(1, ceiling(rows/2), rows)-0.5,
labels=c(1, ceiling(rows/2), rows))
g2 <- g2+opts(panel.grid.minor=theme_line(colour=NA),
panel.grid.major=theme_line(colour=NA),
panel.background=theme_rect(fill=NA, colour=NA),
axis.text.x=theme_text(size=30),
axis.text.y=theme_text(size=30, angle=90),
axis.title.x=theme_text(size=30),
axis.title.y=theme_text(size=30, angle=90), title = title)
heatscale <- c(low='ghostwhite', high='steelblue')
g2 <- g2+scale_fill_gradient("", heatscale[1], heatscale[2], bias = 10)
It works fine, the problem is that the color legend on the right side is too small. Is there a way to make the color legend bigger and increase the font size of the legend?
Thanks,
kz
We don't have your melt.m data, so the code you give is not reproducible. Using the diamonds dataset that comes with ggplot2 as an example, though:
ggplot(diamonds, aes(x=table, y=price)) +
geom_bin2d() +
scale_fill_gradient("", 'ghostwhite', 'steelblue', bias=10) +
opts(legend.key.width=unit(1, "in"),
legend.text = theme_text(size=30))
legend.key.width and legend.text are what you are looking for. I have used exaggerated sizes to make it more obvious.
For more details on the options available, see https://github.com/hadley/ggplot2/wiki/+opts%28%29-List
I tried this and found that R or ggplot2 have changed in the last four years. It yielded the error:
Error: 'opts' is deprecated. Use 'theme' instead. (Defunct; last used in version 0.9.1)
Was able to get it to work with the following instead:
p + theme(legend.text = element_text(size=30),legend.key.size = unit(1, "in"))
Initially tried just changing the text size but had to change the key size with it or it becomes unreadable. Also, unit needs a library explicitly loaded with library(grid)