I have a plot made with GGplot2. Now when i want to change the size of my text points within the plot, the size of the text does not change. I use the following line of code:
ggplot(data = out, aes(x = V2, y = V1)) +
****geom_text(data = out[!is.na(out$V1),], aes(label = labels, alpha=0.3, size=0.1))**** +
facet_grid(id1 ~ id2,scales="fixed")+
geom_text(data=df.text,aes(pos,pos,label=id1)) + geom_abline( slope=1 ) +
ggtitle("Corralation between measured & calculated affinities") +
ylab("") + xlab("") + theme(panel.grid.minor.x=element_blank(), panel.grid.major.x=element_blank())
}
I put ** between start and end of the line of interest fat. I know that size is the right parameter to change, but why isn't my text changing when for instance making size=0.01.
Thanks to Adam Kimberley, the size parameter should be moved outside of the 2nd brackets like this geom_text(data = out[!is.na(out$V1),], aes(label = labels), size=0.1, alpha=0.3)
Than size of the text alters.
Related
I am having problems with changing the axis ticks in a barplot. I am fairly new in using ggplot so the answer might be very obvious.
Here is some data (yes it is strange, but designed to mimic the original dataset I have, which I am not allowed to share):
lab='this is just a very long example text and it will be longer and longer and longer and longer and longer and longer and longer and longer and longer and end'
number=1:20
n=unlist(lapply(number,paste,value=lab))
a=round(runif(n=20,min=-48000,max=-40000))
b=round(runif(n=20,min=-48000,max=-40000))
c=round(runif(n=20,min=-48000,max=-40000))
d=data.frame(cbind(n,a,b,c))
df=pivot_longer(d,cols=c('a','b','c'))
l1=round(as.numeric(min(df$value))/1000 )*1000+1000
l2=round(as.numeric(max(df$value))/1000 )*1000-1000
lim=seq(from=l1,to=l2,by=-1000)
colScale <- scale_fill_manual(name = "n",values = c(rainbow(nrow(df)/3)))
from which I create a barplot
p1=ggplot(df, aes(name, value, fill = as.factor(n))) +
geom_col(position = "dodge",colour='black') +
#scale_y_continuous(breaks = lim , labels = as.character(lim)) +
coord_flip() +
theme_bw() +
theme(axis.text.x=element_text(angle=90),axis.title.x=element_text(face='bold')) +
theme(axis.text.y=element_text(angle=90,size=15)) +
theme(legend.title=element_blank()) +
labs(x = "",y="test") +
colScale +
guides(fill=guide_legend(ncol=1)) +
ggtitle('something') +
theme(plot.title = element_text(hjust = 0.5,size=20))
which is this
that is basically working as I wanted, but the scaling of the x-axis is very unpleasant. What I want instead is an axis, where the breaks and labels are equal to the vector 'lim'. What I understood was that it should be possible to do this by scaling the respective axis as in the commented line. But when I'm trying this I get the error 'Discrete value supplied to continuous scale'. I tried to change the scale to 'scale_y_discrete' but then the ticks disappear completely. I tried everything I could find but nothing worked, so what is wrong?
Based on the answers I changed the plot definition to:
p1=ggplot(df, aes(name, as.numeric(value), fill = as.factor(n))) +
geom_col(position = "dodge",colour='black') +
scale_y_continuous(breaks = lim , labels = as.character(lim)) +
coord_flip() +
theme_bw() +
theme(axis.text.x=element_text(angle=90),axis.title.x=element_text(face='bold')) +
theme(axis.text.y=element_text(angle=90,size=15)) +
theme(legend.title=element_blank()) +
labs(x = "",y="test") +
colScale +
guides(fill=guide_legend(ncol=1)) +
ggtitle('something') +
theme(plot.title = element_text(hjust = 0.5,size=20))
which produced this plot
now I am able to change the axis ticks, but the plot looks nothing like the first one. My goal is to keep the look, meaning showing only the top part of the bars.
I'd suggest converting value to as.numeric (preferably before ggplot, but you can do it within, like below) and using coord_cartesian to specify the "view window". You also might find it simpler to specify your axes in the order you want them, rather than using coord_flip, which is mostly unnecessary since ggplot 3.3.0.
ggplot(df, aes(as.numeric(value), name, fill = as.factor(n))) +
geom_col(position = "dodge",colour='black') +
scale_x_continuous(breaks = lim , labels = as.character(lim)) +
coord_cartesian(xlim = c(min(as.numeric(df$value)), max(as.numeric(df$value))))
# Theming after this up to you
I have done a barplot in RStudio successfully, but I want to decrease the space between the categories (CPLEX and Heurística), but I can't do it. My objective is to make this figures thinner since I am working in a latex file where I want to put two of this plots side by side in the same line, but they are too wide and the get out of the margins. My code is the following.
library("ggplot2")
df <- data.frame(
Metodo = factor(c("CPLEX","Heurística"),levels=c("CPLEX","Heurística")),
Item = factor(c("Demanda total","UE","UI")),
Unidades = c(6440,6291,0,6440,6440,149)
)
ggplot(data=df, aes(x=Metodo, y=Unidades, fill=Item)) +
geom_bar(stat="identity", position=position_dodge(), colour="black",width=0.3) +
theme(text = element_text(family="serif", size=12,face="bold")) +
labs(x = "Método") +
ggtitle("Instancia 1") +
theme(legend.position="top")
ggsave("I1.png")
And the output is
I would like to reduce the wide of this plot, obviously without deforming it. Any ideas?
Add width into position_dodge:
ggplot(data=df, aes(x=Metodo, y=Unidades, fill=Item)) +
geom_bar(stat="identity", position=position_dodge(width = 0.5), colour="black",width=0.3) +
theme(text=element_text(family="serif", size=12,face="bold"))+labs(x="Método")+ggtitle("Instancia 1")+theme(legend.position="top")
In a previous question, I asked about moving the label position of a barplot outside of the bar if the bar was too small. I was provided this following example:
library(ggplot2)
options(scipen=2)
dataset <- data.frame(Riserva_Riv_Fine_Periodo = 1:10 * 10^6 + 1,
Anno = 1:10)
ggplot(data = dataset,
aes(x = Anno,
y = Riserva_Riv_Fine_Periodo)) +
geom_bar(stat = "identity",
width=0.8,
position="dodge") +
geom_text(aes( y = Riserva_Riv_Fine_Periodo,
label = round(Riserva_Riv_Fine_Periodo, 0),
angle=90,
hjust= ifelse(Riserva_Riv_Fine_Periodo < 3000000, -0.1, 1.2)),
col="red",
size=4,
position = position_dodge(0.9))
And I obtain this graph:
The problem with the example is that the value at which the label is moved must be hard-coded into the plot, and an ifelse statement is used to reposition the label. Is there a way to automatically extract the value to cut?
A slightly better option might be to base the test and the positioning of the labels on the height of the bar relative to the height of the highest bar. That way, the cutoff value and label-shift are scaled to the actual vertical range of the plot. For example:
ydiff = max(dataset$Riserva_Riv_Fine_Periodo)
ggplot(dataset, aes(x = Anno, y = Riserva_Riv_Fine_Periodo)) +
geom_bar(stat = "identity", width=0.8) +
geom_text(aes(label = round(Riserva_Riv_Fine_Periodo, 0), angle=90,
y = ifelse(Riserva_Riv_Fine_Periodo < 0.3*ydiff,
Riserva_Riv_Fine_Periodo + 0.1*ydiff,
Riserva_Riv_Fine_Periodo - 0.1*ydiff)),
col="red", size=4)
You would still need to tweak the fractional cutoff in the test condition (I've used 0.3 in this case), depending on the physical size at which you render the plot. But you could package the code into a function to make the any manual adjustments a bit easier.
It's probably possible to automate this by determining the actual sizes of the various grobs that make up the plot and setting the condition and the positioning based on those sizes, but I'm not sure how to do that.
Just as an editorial comment, a plot with labels inside some bars and above others risks confusing the visual mapping of magnitudes to bar heights. I think it would be better to find a way to shrink, abbreviate, recode, or otherwise tweak the labels so that they contain the information you want to convey while being able to have all the labels inside the bars. Maybe something like this:
library(scales)
ggplot(dataset, aes(x = Anno, y = Riserva_Riv_Fine_Periodo/1000)) +
geom_col(width=0.8, fill="grey30") +
geom_text(aes(label = format(Riserva_Riv_Fine_Periodo/1000, big.mark=",", digits=0),
y = 0.5*Riserva_Riv_Fine_Periodo/1000),
col="white", size=3) +
scale_y_continuous(label=dollar, expand=c(0,1e2)) +
theme_classic() +
labs(y="Riserva (thousands)")
Or maybe go with a line plot instead of bars:
ggplot(dataset, aes(Anno, Riserva_Riv_Fine_Periodo/1e3)) +
geom_line(linetype="11", size=0.3, colour="grey50") +
geom_text(aes(label=format(Riserva_Riv_Fine_Periodo/1e3, big.mark=",", digits=0)),
size=3) +
theme_classic() +
scale_y_continuous(label=dollar, expand=c(0,1e2)) +
expand_limits(y=0) +
labs(y="Riserva (thousands)")
I'm making a multiple lines plot with errorbars. If I don't use the size argument, everything is fine:
# sample data
Response=runif(4)
ResponseMin=Response-Response/5
ResponseMax=Response+Response/5
Cases=rep(c("Case1","Case2"),each=2)
df=data.frame(x=1:2,Average=Response,Lower=ResponseMin,Upper=ResponseMax,Case=Cases)
# let's plot
library(ggplot2)
ggplot(df,aes(x=x,y=Average,colour=Case)) +
geom_line(aes(group=Case)) +
geom_point() +
geom_errorbar(aes(ymin=Lower,ymax=Upper,width=0.25)) +
labs(y="foo",title="Some plot fu")
However, when I modify the line size, I start getting weird stuff:
ggplot(df,aes(x=x,y=Average,colour=Case)) +
geom_line(aes(group=Case, size = 1)) +
geom_point() +
geom_errorbar(aes(ymin=Lower,ymax=Upper,width=0.25)) +
labs(y="foo",title="Some plot fu")
Why the extra legend entry "1"? And when I add a size argument for the errobars, it looks like the size of the lines stays the same, whatever the value of size is:
ggplot(df,aes(x=x,y=Average,colour=Case)) +
geom_line(aes(group=Case, size = 1)) +
geom_point() +
geom_errorbar(aes(ymin=Lower,ymax=Upper,width=0.25, size = 1)) +
labs(y="foo",title="Some plot fu")
ggplot(df,aes(x=x,y=Average,colour=Case)) +
geom_line(aes(group=Case, size = 2)) +
geom_point() +
geom_errorbar(aes(ymin=Lower,ymax=Upper,width=0.25, size = 2)) +
labs(y="foo",title="Some plot fu")
Can you help me figure out what's happening here?
If you set size inside aes you are mapping it to a variable
`1` = 1
and ggplot2 creates a legend. If you just want to set the size, you can do that outside of aes:
geom_line(aes(group=Case), size = 1)
try this, size outside aes()
ggplot(df,aes(x=x,y=Average,colour=Case)) +
geom_line(aes(group=Case), size = 1) +
geom_point() +
geom_errorbar(aes(ymin=Lower,ymax=Upper,width=0.25)) +
labs(y="foo",title="Some plot fu")
I have a plot with pairs of points that are slightly offset. Each pair of points has associated error bars. I have specified that the symbol of the first point in the pair is different from that of the second (closed circle vs open circle). I would like it so that the error bars do not show through the open symbol.
Here is a mock data set:
x = runif(4,-2,2)
x_1 = runif(4,-1,3)
dfr <- data.frame(
x = c(x, x_1),
y = rep(c("A","B","C","D"), 2),
upper = c(x+2, x_1+1),
lower = c(x-2, x_1-2),
type = rep(c("alpha", "beta"), each = 4))
And here is the plot:
dodge=position_dodge(width=0.5)
ggplot(dfr,aes(x=y,y=x,colour=type)) +
geom_point(size=8,aes(shape=type),position=dodge) +
geom_errorbar(aes(ymax=upper,ymin=lower),position = dodge) +
scale_colour_manual(values = c('gray','black')) +
scale_shape_manual(values = c(19,21)) +
coord_flip() +
opts(legend.position="none")
Thanks for any help you can provide!
I can't think of a way to make an 'open' point and not let the errorbar show trough. The only way of doing this would be to fill the points with the same colour as the background, but then your gridlines won't be visible through the point.
To do this, map the fill aesthetic to type, and specify scale_fill_manual with the fill colour grey90 which is the theme_grey setting:
ggplot(dfr,aes(x=y,y=x,colour=type, fill=type)) +
geom_errorbar(aes(ymax=upper,ymin=lower),position = dodge) +
geom_point(size=8,aes(shape=type),position=dodge) +
scale_colour_manual(values = c('gray','black')) +
scale_fill_manual(values=c('grey', 'grey90')) +
scale_shape_manual(values = c(19,21)) +
coord_flip() +
opts(legend.position="none")
Why don't you just use color as shown in the modified code below. It will fill the black circles too. Not sure if that is acceptable.
ggplot(dfr,aes(x=y,y=x,colour=type)) +
geom_point(size=8,position=dodge) +
geom_errorbar(aes(ymax=upper,ymin=lower),position = dodge) +
scale_colour_manual(values = c('gray','black')) +
coord_flip() +
opts(legend.position="none")