I have small data frame of statistical values obtained from different method. you can download from here.Dataset is look like this:
I need to facet (two plot side by side with same y axis labels) two plot of RMSE.SD and MB variable using ggplot2 package in R like the following example figure.
I wrote this code for plotting 1 plot for RMSE.SD variable.
library(ggplot2)
comparison_korea <- read.csv("comparison_korea.csv")
ggplot(data=comparison_korea, aes(R,X))+
geom_point(color = "black", pch=17, alpha=1,na.rm=T, size=4)+
labs(title = "", y = "")+
theme(plot.title= element_text(hjust = 0.5,size = 15, vjust = 0.5, face= c("bold")),
axis.ticks.length = unit(0.2,"cm") ,
panel.border = element_rect(colour = "black", fill=NA, size=0.5),
axis.text.x = element_text(angle = 0, vjust = 0.5, size = 14, hjust = 0.5,margin=margin(4,0,0,0), colour = "black"),
axis.text.y = element_text(angle = 0, vjust = 0.5, size = 14, hjust = 1,margin=margin(0,5,0,0), colour = "black"),
plot.margin = unit(c(1, 1.5, 1, 0.5), "lines"))
You should be able to do something like this:
library(ggplot2)
ds <- read.csv("comparison_korea.csv")
dat <- data.frame(labels = as.character(ds$X),
RMSE.SD = ds$RMSE.SD,
MB = ds$MB)
dat <- reshape2::melt(dat)
ggplot(dat, aes(y = labels, x = value)) +
geom_point(shape = "+", size = 5) +
facet_wrap(~variable) +
xlab("value / reference (mm)") +
ylab("") +
theme_bw()
Related
I'm struggling on how can I rotate the label of count values in geom_histogram. I'd like to rotate the labels, that should be in the top of each bar. I'm using the following code:
Toy example:
ex_tfdp = data.frame(x=rnorm(1000,10,10))
ggplot(ex_tfdp) +
geom_histogram(aes(x = x), boundary = 0,binwidth = 5, color="black", fill="#FFC857")+
stat_bin( geom="text", colour="black", size=3.5,
aes(x = x,label=..count..), angle = 90, vjust = -1.5)+
theme(axis.text.x = element_text(angle = 90, hjust = .5),
panel.background = element_blank(),
legend.position="bottom",
legend.title=element_blank(),
axis.ticks.y=element_blank())
Any hint on how can I change the angle of these values and put them in the top of the each bar?
We don't have your data, but assuming it is similar to the following:
set.seed(2)
my_data <- data.frame(measure = rexp(20000)^1.2 * 150)
Then you can correctly bin your data by switching to geom_text and using stat = "bin". Then you can still pass breaks as an argument to the stat. This allows you to use the geom_text parameter angle to rotate 90 degrees. A bit of hjust and vjust tweaking then gets your labels right:
ggplot(my_data) +
geom_histogram(aes(x = measure), boundary = 0,
binwidth = 100, color="black", fill="#FFC857")+
geom_text(stat = "bin", colour = "black", size = 3.5,
breaks = seq(0,2100,100), hjust = -0.5,
aes(x = measure, label=..count..), vjust = 0.5, angle = 90)+
scale_x_continuous(breaks = seq(0,2100,100),
labels = seq(0,2100,100),
expand = expansion(add = c(0, 0))) +
scale_y_continuous(limits = c(0, 15000)) +
theme(axis.text.x = element_text(angle = 90, hjust = .5),
panel.background = element_blank(),
legend.position="bottom",
legend.title=element_blank(),
axis.ticks.y=element_blank())
I have simplified your example a bit:
require(ggplot2)
require(gridExtra)
set.seed(15)
ex_tfdp = data.frame(x=rnorm(1000,10,10))
original.plot = ggplot(ex_tfdp) +
geom_histogram(aes(x = x), boundary = 0,binwidth = 5, color="black", fill="#FFC857")+
stat_bin( geom="text", colour="black", size=3.5,
aes(x = x,label=..count..), angle = 90, vjust = -1.5)
new.plot = ggplot(ex_tfdp) +
geom_histogram(aes(x = x), boundary = 0, binwidth = 5)+ ylim(c(0, 220)) +
stat_bin( geom="text", colour="black", size=3.5,
aes(x = x,label=..count..), angle = 90, boundary = 0, binwidth = 5, hjust = -.5)
grid.arrange(original.plot, new.plot, ncol=2)
The key here is to keep the boundary = 0 and binwidth = 5 when adding the stat_bin layer.
How to place the numbers centralized and in their correct positions? I have tested numerous parameters but I have not found a solution. Everything was very confusing after coordin_flip (). Observe the image and code below.
Code:
# Package
library(ggplot2)
# Create a dataframe
RATE <- c('IgG','IgG','IgA/IgG','IgA/IgG')
GROUP <- c('Asymptomatic','Symptomatic','Asymptomatic','Symptomatic')
N_POSITIVE <- c(12,100,14,107)
PORCENT <- c(7.05, 58.8, 7.73, 59.1)
df <- data.frame(RATE, GROUP, N_POSITIVE, PORCENT)
# Plot
ggplot(df, aes(x = RATE, y = PORCENT, fill = GROUP)) +
geom_bar(stat="identity", width = 0.5) +
geom_text(aes(label=N_POSITIVE),
vjust = -0.3, color = 'black',
size = 3) +
coord_flip() +
labs(x = '', y = 'Percentage (%)\n') +
scale_fill_manual(values = c("#0073c2", "#efc000")) +
theme_classic() +
theme(
legend.position = "top",
legend.title = element_blank(),
axis.text = element_text(angle = 0, color = "black", size = 10, face = 0),
axis.title.x = element_text(angle = 0, color = "black", size = 12, face = 0))
Image:
Does this do what you want? (minus the other formatting which I left out)
ggplot(df, aes(x = PORCENT, y = RATE, fill = GROUP)) +
geom_col(width = 0.5) +
geom_text(aes(label=N_POSITIVE),
vjust = -0.3, color = 'black', hjust = 1.1,
size = 3, position = "stack")
(Note, since ggplot2 3.3.0 in March 2020, most geom's don't need coord_flip if you assign them to the axis you want. If it doesn't interpret correctly, there's also an "orientation" parameter but that doesn't seem necessary here. Also, geom_col is equal to geom_bar(stat="identity").)
I am trying to generate a barplot with dual Y-axis and error bars. I have successfully generated a plot with error bars for one variable but I don't know how to add error bars for another one. My code looks like this. Thanks.
library(ggplot2)
#Data generation
Year <- c(2014, 2015, 2016)
Response <- c(1000, 1100, 1200)
Rate <- c(0.75, 0.42, 0.80)
sd1<- c(75, 100, 180)
sd2<- c(75, 100, 180)
df <- data.frame(Year, Response, Rate,sd1,sd2)
df
# The errorbars overlapped, so use position_dodge to move them horizontally
pd <- position_dodge(0.7) # move them .05 to the left and right
png("test.png", units="in", family="Times", width=2, height=2.5, res=300) #pointsize is font size| increase image size to see the key
ggplot(df) +
geom_bar(aes(x=Year, y=Response),stat="identity", fill="tan1", colour="black")+
geom_errorbar(aes(x=Year, y=Response, ymin=Response-sd1, ymax=Response+sd1),
width=.2, # Width of the error bars
position=pd)+
geom_line(aes(x=Year, y=Rate*max(df$Response)),stat="identity",color = 'red', size = 2)+
geom_point(aes(x=Year, y=Rate*max(df$Response)),stat="identity",color = 'black',size = 3)+
scale_y_continuous(name = "Left Y axis", expand=c(0,0),limits = c(0, 1500),breaks = seq(0, 1500, by=500),sec.axis = sec_axis(~./max(df$Response),name = "Right Y axis"))+
theme(
axis.title.y = element_text(color = "black"),
axis.title.y.right = element_text(color = "blue"))+
theme(
axis.text=element_text(size=6, color = "black",family="Times"),
axis.title=element_text(size=7,face="bold", color = "black"),
plot.title = element_text(color="black", size=5, face="bold.italic",hjust = 0.5,margin=margin(b = 5, unit = "pt")))+
theme(axis.text.x = element_text(angle = 360, hjust = 0.5, vjust = 1.2,color = "black" ))+
theme(axis.line = element_line(size = 0.2, color = "black"),axis.ticks = element_line(colour = "black", size = 0.2))+
theme(axis.ticks.length = unit(0.04, "cm"))+
theme(plot.margin=unit(c(1,0.1,0.1,0.4),"mm"))+
theme(axis.title.y = element_text(margin = margin(t = 0, r = 4, b = 0, l = 0)))+
theme(axis.title.x = element_text(margin = margin(t = 0, r = 4, b = 2, l = 0)))+
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank())+
ggtitle("SRG3")+
theme(legend.position="top")+
theme( legend.text=element_text(size=4),
#legend.justification=c(2.5,1),
legend.key = element_rect(size = 1.5),
legend.key.size = unit(0.3, 'lines'),
legend.position=c(0.79, .8), #width and height
legend.direction = "horizontal",
legend.title=element_blank())
dev.off()
and my plot is as follows:
A suggestion for future questions: your example is far from being a minimal reproducible example. All the visuals an the annotations are not related to your problem but render the code overly complex which makes it harder for others to work with it.
The following would be sufficient:
ggplot(df) +
geom_bar(aes(x = Year, y = Response),
stat = "identity", fill = "tan1",
colour = "black") +
geom_errorbar(aes(x = Year, ymin = Response - sd1, ymax = Response + sd1),
width = .2,
position = pd) +
geom_line(aes(x = Year, y = Rate * max(df$Response)),
color = 'red', size = 2) +
geom_point(aes(x = Year, y = Rate * max(df$Response)),
color = 'black', size = 3)
(Notice that I've removed stat = "identity" in all geom_s because this is set by default. Furthermore, y is not a valid aestetic for geom_errorbar() so I omitted that, too.)
Assuming that the additional variable you would like to plot error bars for is Rate * max(df$Response)) and that the relevant standard deviation is sd2, you may simply append
+ geom_errorbar(aes(x = Year, ymin = Rate * max(df$Response) - sd2,
ymax = Rate * max(df$Response) + sd2),
colour = "green",
width = .2)
to the code chunk above. This yields the output below.
Considering the following data, I am able to generate a plot which describes how the risk of a react over a time interval changes.
risk_1 <- c(0.121,0.226,0.333,0.167,0.200,0.273,0.138,0.323,0.394,0.250,0.200,0.545,0.190,0.355,0.515,0.333,0.300,0.818)
risk_minus_SE <- c(0.060,0.114,0.198,0.047,0.057,0.097,0.072,0.186,0.247,0.089,0.057,0.280,0.109,0.211,0.352,0.138,0.108,0.523)
risk_plus_SE <- c(0.229,0.398,0.504,0.448,0.510,0.566,0.249,0.499,0.563,0.532,0.510,0.787,0.309,0.531,0.675,0.609,0.603,0.949)
Status <- rep(c(rep('With placebo',3),rep('With drug',3)),3)
durtn <- rep(c('(3-15]','(15-30]','(30-46]'),6)
react <- c(rep("x\u226516",6),rep("x\u226509",6),rep("x\u226504",6))
df1 <- data.frame(risk_1, risk_minus_SE, risk_plus_SE, Status, durtn, react)
dodge <- position_dodge(width=0.45)
ggplot(df1,aes(colour=react, y=risk_1, x=durtn)) +
geom_point(aes(shape=durtn), shape=16, size = 5, position=dodge) +
geom_errorbar(aes(ymin=risk_minus_SE, ymax=risk_plus_SE), position = dodge, width=0.5, size=1, lty=1) +
scale_colour_manual(values = c('black','red','blue')) +
facet_grid(~Status) +
scale_shape_manual(values = c(8,19))+
theme_bw() +
scale_x_discrete(limits=c('(3-15]','(15-30]','(30-46]')) +
coord_cartesian(ylim = c(0, 0.8)) +
theme(legend.position = c(.1, .85), legend.background = element_rect(colour = "black"),
plot.title = element_text(lineheight=1.5, face="bold", size=rel(1.5), hjust = 0.5),
panel.grid.major.x = element_blank(),
axis.text.x = element_text(vjust=0.5, size=16),
axis.text.y = element_text(vjust=0.5, size=16),
axis.title.y = element_text(size=20),
axis.title.x = element_text(size=20),
legend.text = element_text(size = 16, face = "bold"),
strip.text = element_text(size=25)) +
xlab("\ntime (min)") + ylab("Risk")
What I want to do is overlay a series of points at given x and y coordinates.
That being at With drug & durtn==(3,15], manually insert points at.....
Risk==0.5 for react=x≥04 in black
Risk==0.2 for react=x≥09 in red
Risk==0.0 for react=x≥16 in blue
Such that the desired output should look like
How does one use the geom_point() in combination with a facet_grid and dodge
First, you have to create a separate data frame that contains the data for the additional points.
dat <- data.frame(risk_1 = c(0.5, 0.2, 0),
react = levels(df1$react),
durtn = '(3-15]',
Status = 'With drug')
This new data frame dat can be used with geom_point to add an additional layer to the existing plot.
+ geom_point(data = dat, position = dodge, shape = 4, size = 5, show.legend = FALSE)
Running in R this code:
# example data
x = runif(14, 0.0, 1.0)
norm = x/sum(x)
data = data.frame(replicate(17,sample(norm)))
require(ggplot2)
require(reshape2)
data$no <- seq_len(nrow(data))
data_molten <- melt(data, id.vars = "no")
data_molten[data_molten == 0] <- NA
View(data_molten)
# ggplot
ggplot(data_molten[!is.na(data_molten$value),], aes(x = variable, y = value, fill = factor(no))) +
geom_bar(stat = "identity") +
scale_fill_hue(l=40) + facet_grid(no~.) + theme_minimal() +
theme(legend.position="none",
axis.text.x = element_text(angle = 90, colour="black", vjust = 0.5, hjust=1, size=16),
axis.title.x = element_blank(), axis.title.y = element_blank(),
axis.line.y=element_blank(), axis.text.y=element_blank(), axis.ticks.y=element_blank(),
strip.text.y=element_text(size = 16, colour="black", family="", angle=00,hjust = 0),
panel.grid=element_blank(),
axis.line=element_line(size = 1, colour = "black", linetype = "solid"),
axis.ticks.x=element_line(size = 1, colour = "black", linetype = "solid"),
panel.background=element_blank())
produces this plot:
Anybody knows how can I add a vertical line between the right side of the plot and the layers' labels (the 1, 2, 3, ..., 14) which have a tick per layer's label, keeping enough space between the plot, the axis and the labels?
EDIT:
Running
num_var_x = 14
num_var_y = 17
x = runif(num_var_x, 0.0, 1.0)
norm = x/sum(x)
data = data.frame(replicate(num_var_y,sample(norm)))
## preparing dataset for ggplot
require(ggplot2)
require(reshape2)
data$no <- seq_len(nrow(data))
data_molten <- melt(data, id.vars = "no")
data_molten_sort = data_molten[with(data_molten,order(no)),]
## removing elements from variable 'no' whose max. value is e.g. < 0.025
sequence = seq(from=1, to=(num_var_y*num_var_x-num_var_x)+1, by=num_var_x)
for(i in 1:length(sequence))
{
if(isTRUE((max(data_molten_sort$value[(sequence[i]):((num_var_x+sequence[i])-(1))])) < 0.025))
{
data_molten_sort$value[(sequence[i]):((num_var_x+sequence[i])-(1))] = NA
}
}
View(data_molten)
## preparing posterior exporting
#install.packages("Cairo"); "cairo" type in png() has a better quality
library("Cairo")
#preparing exporting
png(file="ggplot.png",type="cairo", width = 4, height = 5, units = 'in',pointsize=8,res=600)
## plotting
ggplot(data_molten[!is.na(data_molten$value),], aes(x = variable, y = value, fill = factor(no))) +
geom_bar(stat = "identity") +
scale_fill_hue(l=40) + facet_grid(no~., as.table=FALSE, scale="free_y", space = "free_y") + theme_minimal() +
geom_vline(xintercept=max(as.numeric(data_molten$variable)) + 0.586, size=0.3) +
theme(legend.position="none",
axis.text.x = element_text(angle = 90, colour="black", vjust = 0.4, hjust=1, size=8),
axis.title.x = element_blank(), axis.title.y = element_blank(),
axis.line.y=element_blank(), axis.text.y=element_blank(), axis.ticks.y=element_blank(),
strip.text.y=element_text(size = 8, colour="black", family="", angle=00,hjust = 0.1),
panel.grid=element_blank(),
axis.line=element_line(size = 0.3, colour = "black", linetype = "solid"),
axis.ticks.x=element_line(size = 0.3, colour = "black", linetype = "solid"),
panel.background=element_blank(), panel.margin = unit(0, "lines"))
## exporting barplot "ggplot.png" to directory
dev.off()
now the y line is continuous, plus other additions such as an exporting command.
http://i.imgur.com/C6h5fPg.png?1
Assuming that your original plot is saved in an object p1, this could be a solution:
p1 + geom_vline(xintercept=max(as.numeric(data_molten$variable))+0.5, size=1) + #data-dependent
scale_x_discrete(expand=c(0,0))+ #create nicer corner
theme(
#move labels slightly to the right with hjust
strip.text.y=element_text(size = 16, colour="black", family="", angle=00,hjust = 0.5)
)