I'm assigned to create an Odds of Ratio ggplot in R. The plot I'm supposed to create is given below.
Given plot
My job is to figure out codes which creates the exact plots in R. I've done most parts. Here is my work.
My work
Before jumping into my code, it is very important that I am not using the correct values for boxOdds, boxCILow, and boxCIHigh since I have not figured out the correct values. I wanted to figure out codes for ggplot first so I can enter the right values as soon as I find them.
This is the code I used:
library(ggplot2)
boxLabels = c("Females/Males", "Student-Centered Prac. (+1)", "Instructor Quality (+1)", "Undecided / STM",
"non-STEM / STM", "Pre-med / STM", "Engineering / STM", "Std. test percentile (+10)",
"No previous calc / HS calc", "College calc / HS calc")
df <- data.frame(yAxis = length(boxLabels):1,
boxOdds =
c(2.23189, 1.315737, 1.22866, 0.8197413, 0.9802449, 0.9786673, 0.6559005, 0.5929812, 0.6923759, 1.3958275),
boxCILow =
c(.7543566,1.016,.9674772,.6463458,.9643047,.864922,.4965308,.3572142, 0.4523759, 1.2023275),
boxCIHigh =
c(6.603418,1.703902,1.560353,1.039654,.9964486,1.107371,.8664225,.9843584, 0.9323759, 1.5893275)
)
(p <- ggplot(df, aes(x = boxOdds, y = boxLabels)) +
geom_vline(aes(xintercept = 1), size = 0.75, linetype = 'dashed') +
geom_errorbarh(aes(xmax = boxCIHigh, xmin = boxCILow), size = .5, height =
0, color = 'gray50') +
geom_point(size = 3.5, color = 'orange') +
theme_bw() +
theme(panel.grid.minor = element_blank()) +
scale_x_continuous(breaks = seq(0,7,1) ) +
ylab('') +
xlab('Odds Ratio') +
annotate(geom = 'text', y =1.1, x = 3.5, label ='',
size = 3.5, hjust = 0) + ggtitle('Estimated Odds of Switching') +
theme(plot.title = element_text(hjust = 0.5, size = 30),
axis.title.x = (element_text(size = 15))) +
theme(panel.grid.minor = element_blank(), panel.grid.major = element_blank())
)
p
Where I'm stuck at:
Removing small vertical lines on the beginning and end of each row's CI). I was not sure what it's called so I was having hard time looking it up. SOLVED
I'm also stuck at coloring specific rows in different colors.
The last part I'm stuck at is assigning proper order of each variable for y-axis. As you can see in my code ("boxLabels" part), I have put all the variables in order of given plot but it seems like the R didn't care about the order. So the varaible located at the very top is "Undecided / STM", instead of "Females / Males".
How do I decrease the space from 0 to 1? SOLVED
Any help would be appreciated!
First, probably you want ggstance::geom_pointrangeh. Second, you could define colors by yAxis right at the beginning. To group some factors create a new variable group. Third is related to your data where you could assign factor labels. Fourth, remove coord_trans as suggested by #beetroot.
Assign factor labels
dat$yAxis <- factor(dat$yAxis, levels=10:1, labels=rev(boxLabels))
Create groups
dat$group <- 1
dat$group[which(dat$yAxis %in% c("Females/Males", "Undecided / STM", "non-STEM / STM",
"Pre-med / STM"))] <- 2
dat$group[which(dat$yAxis %in% c("Student-Centered Prac. (+1)",
"No previous calc / HS calc",
"College calc / HS calc"))] <- 3
Colors
colors <- c("#860fc2", "#fc691d", "black")
Plot
library(ggplot2)
library(ggstance)
ggplot(dat, aes(x=boxOdds, y=yAxis, color=as.factor(group))) +
geom_vline(aes(xintercept=1), size=0.75, linetype='dashed') +
geom_pointrangeh(aes(xmax=boxCIHigh, xmin=boxCILow), size=.5,
show.legend=FALSE) +
geom_point(size=3.5, show.legend=FALSE) +
theme_bw() +
scale_color_manual(values=colors)+
theme(panel.grid.minor=element_blank()) +
scale_x_continuous(breaks=seq(0,7,1), limits=c(0, max(dat[2:4]))) +
ylab('') +
xlab('Odds Ratio') +
annotate(geom='text', y =1.1, x=3.5, label ='',
size=3.5, hjust=0) + ggtitle('Estimated Odds of Switching') +
theme(plot.title=element_text(hjust=.5, size=20)) +
theme(panel.grid.minor=element_blank(), panel.grid.major=element_blank())
Gives
Data
dat <- structure(list(yAxis = 10:1, boxOdds = c(2.23189, 1.315737, 1.22866,
0.8197413, 0.9802449, 0.9786673, 0.6559005, 0.5929812, 0.6923759,
1.3958275), boxCILow = c(0.7543566, 1.016, 0.9674772, 0.6463458,
0.9643047, 0.864922, 0.4965308, 0.3572142, 0.4523759, 1.2023275
), boxCIHigh = c(6.603418, 1.703902, 1.560353, 1.039654, 0.9964486,
1.107371, 0.8664225, 0.9843584, 0.9323759, 1.5893275)), class = "data.frame", row.names = c(NA,
-10L))
Related
This is not my data (for confidentiality reasons), but I have tried to create a reproducible example using a dataset included in the ggplot2 library. I have an histogram summarizing the value of some variable by group (factor of 2 levels). First, I did not want the counts but proportions of the total, so I used that code:
library(ggplot2)
library(dplyr)
df_example <- diamonds %>% as.data.frame() %>% filter(cut=="Premium" | cut=="Ideal")
ggplot(df_example,aes(x=z,fill=cut)) +
geom_histogram(aes(y=after_stat(width*density)),binwidth=1,center=0.5,col="black") +
facet_wrap(~cut) +
scale_x_continuous(breaks=seq(0,9,by=1)) +
scale_y_continuous(labels=scales::percent_format(accuracy=2,suffix="")) +
scale_fill_manual(values=c("#CC79A7","#009E73")) +
labs(x="Depth (mm)",y="Count") +
theme_bw() + theme(legend.position="none")
It gave me this as a result.
enter image description here
The issue is that I would like to print the numeric percentages on top of the bins and haven't find a way to do so.
As I saw it done for printing counts elsewhere, I attempted to print them using stat_bin(), including the same y and label values as the y in geom_histogram, thinking it would print the right numbers:
ggplot(df_example,aes(x=z,fill=cut)) +
geom_histogram(aes(y=after_stat(width*density)),binwidth=1,center=0.5,col="black") +
stat_bin(aes(y=after_stat(width*density),label=after_stat(width*density*100)),geom="text",vjust=-.5) +
facet_wrap(~cut) +
scale_x_continuous(breaks=seq(0,9,by=1)) +
scale_y_continuous(labels=scales::percent_format(accuracy=2,suffix="")) +
scale_fill_manual(values=c("#CC79A7","#009E73")) +
labs(x="Depth (mm)",y="%") +
theme_bw() + theme(legend.position="none")
However, it does print way more values than there are bins, these values do not appear consistent with what is portrayed by the bar heights and they do not print in respect to vjust=-.5 which would make them appear slightly above the bars.
enter image description here
What am I missing here? I know that if there was no grouping variable/facet_wrap, I could use after_stat(count/sum(count)) instead of after_stat(width*density) and it seems that it would have fixed my issue. But I need the histograms for both groups to appear next to each other. Thanks in advance!
You have to use the same arguments in stat_bin as for the histogram when adding your labels to get same binning for both layers and to align the labels with the bars:
library(ggplot2)
library(dplyr)
df_example <- diamonds %>%
as.data.frame() %>%
filter(cut == "Premium" | cut == "Ideal")
ggplot(df_example, aes(x = z, fill = cut)) +
geom_histogram(aes(y = after_stat(width * density)),
binwidth = 1, center = 0.5, col = "black"
) +
stat_bin(
aes(
y = after_stat(width * density),
label = scales::number(after_stat(width * density), scale = 100, accuracy = 1)
),
geom = "text", binwidth = 1, center = 0.5, vjust = -.25
) +
facet_wrap(~cut) +
scale_x_continuous(breaks = seq(0, 9, by = 1)) +
scale_y_continuous(labels = scales::number_format(scale = 100)) +
scale_fill_manual(values = c("#CC79A7", "#009E73")) +
labs(x = "Depth (mm)", y = "%") +
theme_bw() +
theme(legend.position = "none")
I have an issue with ggplot2 plotting system with R.
I would like to print a graph, scatterplot + smoothing with two grades (ref) and two variable each (Vix, monomer), with vix referring to the left y-Axis and monomer referring to the right y-Axis. I would like to have red and blue dark colour for ref at 130°C and the same but pale colours for the 150°C one. Colours are the followings, but for understanding it is not really important:'#644196', '#bba6d9', '#f92410', '#fca49c'. In this way I would obtain 4 lines with 4 different colours.
I used to define the colours according the command:
scale_color_manual(values=c('#644196', '#bba6d9', '#f92410', '#fca49c')) +
The problem is that I obtain 4 lines but only two colours and also the legend has only two assignments (and not 4 as i expected). It looks like it changes the colours over the ref and it doesn't assign any colour change to the two variables Vix and monomer.
Below I report the whole code.
Dati <- data.frame("Vix" = c(62500, 87000, 122000, 140000, 82700, 73000, 110000, 110000, 140300, 81500), "monomer" = c(0.089,0.08,0.095,0.1,0.111, 0.09, 0.094, 0.099, 0.111, 0.197), "Time" = c(30, 60, 90, 120, 135, 30, 60, 90, 120, 135), "ref" = c('130°C', '130°C', '130°C', '130°C', '130°C', '150°C', '150°C', '150°C', '150°C', '150°C'))
attach(Dati)
library(ggplot2)
library(readxl)
####Graph processing
scaleFactor <- max(Vix) / max(monomer)
Graph <- ggplot(Dati, aes(x= Time, col=(ref))) +
geom_point(aes(y= Vix, col=(ref)), shape = 1, size = 3.5) +
geom_smooth(aes(y= Vix), method="loess") +
geom_point(aes(y= monomer * scaleFactor, col=ref), shape = 1, size = 3.5) +
geom_smooth(aes(y=monomer * scaleFactor), method="loess") +
scale_color_manual(values=c('#644196', '#bba6d9', '#f92410', '#fca49c')) +
scale_y_continuous(name="Vix", sec.axis=sec_axis(~./scaleFactor, name="monomer")) +
theme(
axis.title.y.left=element_text(color='#f92410'),
axis.text.y.left=element_text(color='#f92410'),
axis.title.y.right=element_text(color='#644196'),
axis.text.y.right=element_text(color='#644196')
)
Graph
Obtained output graph
Is somebody able to understand wht could I do in order to fix this issue?
Thank you in advance for every your possible kind reply.
Probably the easiest way is to add information to the variable at the specification of aesthetics. In the example below, we paste0() the extra information whether the series is Vix or monomer to the colours.
Graph <- ggplot(Dati, aes(x= Time)) +
geom_point(aes(y= Vix, col=paste0("Vix ", ref)), shape = 1, size = 3.5) +
geom_smooth(aes(y= Vix, col = paste0("Vix ", ref)), method="loess") +
geom_point(aes(y= monomer * scaleFactor, col=paste0("Monomer ", ref)), shape = 1, size = 3.5) +
geom_smooth(aes(y=monomer * scaleFactor, col = paste0("Monomer ", ref)), method="loess") +
scale_color_manual(values=c('#644196', '#bba6d9', '#f92410', '#fca49c'),
name = "Series?") +
scale_y_continuous(name="Vix", sec.axis=sec_axis(~./scaleFactor, name="monomer")) +
theme(
axis.title.y.left=element_text(color='#f92410'),
axis.text.y.left=element_text(color='#f92410'),
axis.title.y.right=element_text(color='#644196'),
axis.text.y.right=element_text(color='#644196')
)
Graph
You have 2 colors because your variable mapped to color (ref) has 2 distinct values. I guess you would like to have Vix and monomer curves for each value of ref. You can get that by getting your data into long format and creating new variable that refers to temperature and to Vix or monomer:
scaleFactor <- max(Dati$Vix) / max(Dati$monomer)
STEP 1: calculate monomer, create column that tells you if value if Vix or monomer (long format for those two variables), and recreate ref
Dati <- Dati %>%
mutate(
monomer = monomer * scaleFactor
) %>%
pivot_longer(cols = c(Vix, monomer)) %>%
mutate(ref = str_c(ref, name, sep = "-"))
STEP 2 map ref to color aesthetic (long format is neat for ggplot2)
ggplot(Dati, aes(Time, value, color = ordered(ref, levels = unique(ref)))) +
geom_point(shape = 1, size = 3.5) +
geom_smooth(method = "loess") +
scale_color_manual("groups", values = c('#fca49c', '#bba6d9', '#f92410', '#644196')) +
scale_y_continuous(name = "Vix", sec.axis = sec_axis(~./scaleFactor, name = "monomer")) +
theme(
axis.title.y.left = element_text(color = '#f92410'),
axis.text.y.left = element_text(color = '#f92410'),
axis.title.y.right = element_text(color = '#644196'),
axis.text.y.right = element_text(color = '#644196')
)
RESULT:
I'm trying to make a bar chart with a 3rd variable (which in this case is "frequency") where the 3rd variable changes the width of the bars (higher frequency = larger width). Obviously I have to figure out the sizing, but that is just aesthetics and I can figure that out later. When I use this code I keep getting the error "position_dodge requires non-overlapping x intervals" and the plot then stacks the bars instead of grouping them. Also (maybe this could help) wondering if there is a way to increase the distance between labels on the x-axis (meaning increase the distance between "Iso", "Transition", "P&R Handler", etc.)
All help appreciated.
library(tidyverse)
library(ggrepel)
percentile_playtype = c(70.10, 41.20, 83.90, 0, 0, 97.30, 40, 0, 49.30, 20.10, 88.90, 91.80,
94.60, 0, 83.60, 86.90, 42, 41.10, 46.90, 0, 81.50, 84.00)
frequency = c(8.5,16.5,53.3,0,0,6,7.2,0,2.1,0.6,5.4,1.9,12.4,0,28,8.1,16,1.9,13.6,0,10.6,6.1)
v1 = sqrt(sqrt(sqrt(frequency)))/10
lowsize <- element_text(size=8)
playtype = c("Iso","Transition","P&R Handler","P&R Roll","Post Up","Spot Up",
"Handoff","Cut","Off Screen","Putbacks","Misc")
Player = rep(c("Trae Young","John Collins"), each=11)
PlayData <- data.frame(percentile_playtype,frequency,playtype,Player)
a1 <- ggplot(PlayData, aes(fill=Player, y=percentile_playtype, x=playtype)) +
geom_bar(position="dodge", stat="identity",width=v1)
a1
If you really want frequency to be mapped to bar width, you need to do it the hard way, and calculate those widths, plotting geom_rect rather than geom_bar. From a visual impact point of view it is better to scale the area of the bars rather than their absolute width:
PlayData$playtype_n <- as.numeric(as.factor(PlayData$playtype))
PlayData$frequency_n <- PlayData$frequency/max(PlayData$frequency) * 0.5 /
(PlayData$percentile_playtype / 100) *
(2 * as.numeric(as.factor(PlayData$Player)) - 3) +
as.numeric(as.factor(PlayData$playtype))
ggplot(PlayData, aes(fill = Player)) +
geom_rect(aes(xmin = playtype_n, xmax = frequency_n, ymin = 0,
ymax = percentile_playtype)) +
scale_x_continuous(breaks = sort(unique(PlayData$playtype_n)),
labels = levels(as.factor(PlayData$playtype))) +
scale_fill_manual(values = c("deepskyblue4", "orange")) +
labs(x = "Play type (area scaled to frequency)", y = "Percentile playtype") +
theme_bw()
Personally, I don't think this looks great, and I'm not convinced it's worth the trouble. Another, easier to understand approach might be to use facets
ggplot(PlayData, aes(fill=frequency, y=percentile_playtype, x=playtype)) +
geom_col(position = "dodge", width=0.75) +
geom_text(aes(label = frequency), vjust = 1.5, color = "white") +
facet_wrap(Player~., ncol = 1) +
scale_fill_viridis_c() +
theme_classic() +
theme(panel.grid.major.y = element_line(color = "gray90"),
strip.background = element_blank(),
strip.text.x = element_text(size = 16),
axis.line.x.bottom = element_line())
Or perhaps a labelled scatter plot using ggrepel:
ggplot(PlayData, aes(percentile_playtype, frequency, color = Player)) +
geom_point() +
geom_text_repel(aes(label = playtype), size = 5) +
scale_color_manual(values = c("deepskyblue4", "orange")) +
theme_bw()
Are you trying to mimic something like a mosaic plot?
percentile_playtype = c(70.10, 41.20, 83.90, 0, 0, 97.30, 40, 0, 49.30, 20.10, 88.90, 91.80,
94.60, 0, 83.60, 86.90, 42, 41.10, 46.90, 0, 81.50, 84.00)
frequency = c(8.5,16.5,53.3,0,0,6,7.2,0,2.1,0.6,5.4,1.9,12.4,0,28,8.1,16,1.9,13.6,0,10.6,6.1)
v1 = sqrt(sqrt(sqrt(frequency)))/10
playtype = c("Iso","Transition","P&R Handler","P&R Roll","Post Up","Spot Up",
"Handoff","Cut","Off Screen","Putbacks","Misc")
Player = rep(c("Trae Young","John Collins"), each=11)
PlayData <- data.frame(percentile_playtype,frequency,playtype,Player)
CGPfunctions::PlotXTabs2(PlayData,
x = playtype,
y = Player,
counts = percentile_playtype,
plottype = "mosaic",
x.axis.orientation = "slant",
sample.size.label = FALSE,
label.text.size = 2)
I am currently plotting data using the ggpubr package in R (based on ggplot2). When I plot the means of two conditions including standard errors, the y-axis should be limited from 1 to 7, which I indicate using:
p <- ggline(data, x = "condition", y = "measure",
add = c("mean_se"),
ylab = "Measure")
ggpar(y, ylim = c(1, 7), ticks=T, yticks.by = 1)
In the final plot, however, the y-axis shows only values from 1 to 6
I tried to plot the same data using native ggplot2, but the problem persists, once I change the layout.
For ggplot2 I used:
p <- ggplot(data, aes(x=condition, y=measure)) +
geom_line() +
geom_point()+
geom_errorbar(aes(ymin=measure-se, ymax=measure+se), width=.2, position=position_dodge(0.05)) +
ylab("measure") +
xlab("Condition")
p + scale_y_continuous(name="measure", limits=c(1, 7), breaks=c(1:7))
p + theme_classic()
It would be great if someone could help me with this issue.
Edit:
as suggested in the comments, here is the data I am trying to plot using ggplot2:
structure(list(condition = structure(3:4, .Label = c("IC", "SC",
"ILC", "SLC"), class = "factor"), measure = c(4.10233918128655, 3.83040935672515
), se = c(0.235026318386523, 0.216811675834834)), class = "data.frame", row.names = c(NA,
-2L))
I think I got something resembling your plot with correct y-axes with the following code:
ggplot(data, aes(x = condition, y = measure)) +
geom_point() +
geom_errorbar(aes(ymin = measure-se, ymax = measure+se),
width = .2, position = position_dodge(0.05)) +
# Group prevents geom_line interpreting each x-axis point as it's own group
geom_line(aes(group = rep(1, nrow(data)))) +
xlab("Condition") +
# Expand is optional, it prevents padding beyond 1 and 7
scale_y_continuous(name = "measure",
limits = c(1, 7),
breaks = 1:7,
expand = c(0,0)) +
theme_classic()
The solution is much more trivial. You were doing everything right! Except for one clerical error. Here is what was happening:
First, you generate your initial plot, fine.
p <- ggplot(data, aes(x=condition, y=measure)) +
geom_line() + geom_point() +
geom_errorbar(aes(ymin=measure-se, ymax=measure+se),
width=.2, position=position_dodge(0.05)) +
ylab("measure") +
xlab("Condition")
This plot does not have the limits. When you add the limits and display it, the scales are correct:
p + scale_y_continuous(name="measure", limits=c(1, 7), breaks=c(1:7))
However, note that p did not change! You did not store the result of adding the limits to p. Therefore, p is still without the scale_y_continuous. No wonder then that when you type
p + theme_classic()
...the limits are gone. However, if you try
p <- p + scale_y_continuous(name="measure", limits=c(1, 7), breaks=c(1:7))
p + theme_classic()
everything will be correct.
I am trying to scale my y-axis to work like this:
So I tried the following:
scale_y_continuous(breaks=c(0, 0.9, 0.99, 0.999))
However, the results are:
How can I scale the graph accordingly to the numbers specified? More specifically, can I scale the graph according to an array of values? say c = (0, 0.9, 0.99, 0.999).
Here's the code I wrote so far:
library(ggplot2)
library(extrafont)
library(scales)
results = read.csv("results.csv")
breaks = c(0, 0.9, 0.99, 0.999)
ggplot(data=results, aes(x=t, y=Values, group=Algorithm, color = factor(Algorithm), shape = factor(Algorithm))) +
geom_line(size = 1)+
theme_bw() +
theme(legend.position="top") +
labs(color="") +
theme(axis.text=element_text(size=14),
axis.title=element_text(size=16),
legend.text=element_text(size=16)) +
scale_y_log10(breaks=breaks, labels=breaks)
Sample CSV data:
t,Algorithm,Values
0,alg1,0.000000000000
0,alg2,0.000000000000
0,alg3,0.000000000000
0,alg4,0.000000000000
0,alg5,0.000000000000
100,alg1,0.950000000000
100,alg2,0.950000000000
100,alg3,0.950000000000
100,alg4,0.000000000147
100,alg5,0.000000000000
200,alg1,0.950000000005
200,alg2,0.950000000000
200,alg3,0.950000001250
200,alg4,0.004578701861
200,alg5,0.000000182645
250,alg1,0.950000259280
250,alg2,0.950000000000
250,alg3,0.950000400517
250,alg4,0.219429576450
250,alg5,0.000199361725
300,alg1,0.950314820965
300,alg2,0.950000000000
300,alg3,0.950037201876
300,alg4,0.824669958806
300,alg5,0.012390843342
400,alg1,0.992274938722
400,alg2,0.950000000000
400,alg3,0.959167637150
400,alg4,0.936487596777
400,alg5,0.603221722035
500,alg1,0.998314400000
500,alg2,0.998334835568
500,alg3,0.995747486022
500,alg4,0.978514678505
500,alg5,0.917973600000
600,alg1,0.998314400000
600,alg2,0.999100000000
600,alg3,0.999118983394
600,alg4,0.998040800000
600,alg5,0.917973600000
From what I understand from your data, it seems that you want to zoom in your plot to see how data in the range (0.9 - 0.99) is distributed. In ggplot it is recommend to use facets that help highlight the important segments in your data.
You can choose to create facets by dividing your data into multiple segments (range in your case) of interest. Something like below creates 3 segments out of your range.
library(dplyr)
results = results %>%
mutate(grp = case_when(Values<0.9 ~ "0 - 0.9",
Values>=0.9 & Values<0.99 ~ "0.9 - 0.99",
Values>=0.99 ~ "0.99+"))
results %>%
ggplot(aes(x = t, y = Values, group = Algorithm, color = Algorithm)) +
geom_line(size = 1) +
facet_wrap(~grp, scales = "free") +
theme(legend.position="top") +
labs(color="") +
theme(axis.text=element_text(size=14),
axis.title=element_text(size=16),
legend.text=element_text(size=16))
Alternately, you can choose to display the whole data in one chart and create facets with the segments of your choice. Below I show only one segment in which you can zoom in.
plot_df = bind_rows(`All Data` = results,
`Segment (0.9 - 0.99)` = results %>% filter(grp=="0.9 - 0.99"),
.id = "Groups")
plot_df %>%
ggplot(aes(x = t, y = Values, group = Algorithm, color = Algorithm)) +
geom_line(size = 1) +
facet_wrap(~Groups, scales = "free") +
theme(legend.position="top") +
labs(color="") +
theme(axis.text=element_text(size=14),
axis.title=element_text(size=16),
legend.text=element_text(size=16))
It is not a good idea to break scale in one plot as it may lead to wrong interpretations by users.
Edit:
The graph in your question is reproducible using a user-defined scale transform as below.
library(scales)
foo_trans = function() trans_new("foo", function(x) log(1/(1-x)), function(x) -1/exp(x) + 1)
results %>%
ggplot(aes(x = t, y = Values, group = Algorithm, color = Algorithm)) +
geom_line(size = 1) +
theme(legend.position="top") +
labs(color="") + ylab("Values (Tranformed Scale)") +
theme(axis.text=element_text(size=14),
axis.title=element_text(size=16),
legend.text=element_text(size=16)) +
scale_y_continuous(breaks = c(0,0.9,0.99,0.999), labels = c(0,0.9,0.99,0.999)) +
coord_trans(y = "foo")
As you see for your toy example, the y-axis was transformed using the code and no data transformation was applied. Computationally this can be done, I but I will prefer the first solution for representation. You may want to refer to additional answers here and here to work out your actual problem.
You're looking for scale_y_log10
replace scale_y_continuous(breaks=c(0, 0.9, 0.99, 0.999)) with scale_y_log10(breaks=c(0, 0.9, 0.99, 0.999))