Reduce space between y axis and cathegories in a ggplot - r

I have made the graph below with ggplot. I would like to reduce the distance between the y axis and the first category (a). Which function should I use? Thanks! :)
library(ggplot2)
library(reshape2)
data <- data.frame(a = rnorm(10), b = rnorm(10), c = rnorm(10), group = 1:10)
data <- melt(data, id = "group")
ggplot(data, aes(x = variable, y = value, group = group, color = as.factor(group))) + geom_point() + geom_line() + theme_minimal() + theme(axis.line = element_line(), panel.grid = element_blank())

Suppose we have the following plot:
library(ggplot2)
df <- data.frame(x = rep(LETTERS[1:3], 3),
y = rnorm(9),
z = rep(letters[1:3], each = 3))
ggplot(df, aes(x, y, colour = z, group = z)) +
geom_line() +
geom_point()
We can reduce the space between the extreme points and the panel edges by adjusting the expand argument in a scale function:
ggplot(df, aes(x, y, colour = z, group = z)) +
geom_line() +
geom_point() +
scale_x_discrete(expand = c(0,0.1))
Setting expand = c(0,0) completely removes the space. The first argument is a relative number, the second an absolute; so in the example above we set the expand to 0.1 x-axis units.

Related

Make geom_histogram display x-axis labels as integers instead of numerics

I have a data.frame that has counts for several groups:
set.seed(1)
df <- data.frame(group = sample(c("a","b"),200,replace = T),
n = round(runif(200,1,2)))
df$n <- as.integer(df$n)
And I'm trying to display a histogram of df$n, facetted by the group using ggplot2's geom_histogram:
library(ggplot2)
ggplot(data = df, aes(x = n)) + geom_histogram() + facet_grid(~group) + theme_minimal()
Any idea how to get ggplot2 to label the x-axis ticks with the integers the histogram is summarizing rather than the numeric values it is currently showing?
You could tweak this by the binwidth argument of geom_histogram:
library(ggplot2)
ggplot(data = df, aes(x = n)) +
geom_histogram(binwidth = 0.5) +
facet_grid(~group) +
theme_minimal()
Another example:
set.seed(1)
df <- data.frame(group = sample(c("a","b"),200,replace = T),
n = round(runif(200,1,5)))
library(ggplot2)
ggplot(data = df, aes(x = n)) +
geom_histogram(binwidth = 0.5) +
facet_grid(~group) +
theme_minimal()
You can manually specify the breaks with scale_x_continuous(breaks = seq(1, 2)). Alternatively, you can set the breaks and labels separately as well.

Color outlier dots above a specific value in R

How do I color outliers that are above a specific value using ggplot2 in R?.
(Sorry for the seemingly easy question, I am a beginner. the reason why is that these are frequencies of a value of 0, I am then transforming this column of data by taking the -log10(). So anything that has a frequency of 0 would then be transformed into Inf. Attached is a screenshot of my plot, essentially I want to make all the outlier points above 10 on the y axis to be a different color.
boxplots <- function(df){
df$'frequency'[is.na(df$'frequency')] <- 0.00
df$'-log10(frequency)' <- -log10(df$'frequency')
x <- data.frame(group = 'x', value = df$'-log10(frequency)'[df$'Type'=='x'])
y <- data.frame(group = 'y', value = df$'-log10(frequency)'[df$'Type'=='y'])
z <- data.frame(group = 'z', value = df$'-log10(frequency)'[df$'Type'=='c=z'])
plot.data <<- rbind(x, y, z)
labels <- c("z", "y", "z")
t<-plot.data %>%
ggplot(aes(x = group, y = value, fill = group))+
geom_boxplot()+
scale_fill_viridis(discrete = TRUE, alpha = 0.6)+
geom_jitter(color="black", size=0.4, alpha=0.9) +
theme_ipsum() +
theme(
legend.position="none",
plot.title = element_text(size=11)
) +
ggtitle("Distribution of -log10(frequency) by Type") +
xlab("Type")+
ylab("-log10(frequency)")+
scale_x_discrete(labels=labels)+
scale_y_continuous(limits = c(0, 10), breaks = seq(0, 10, by = 2))
print(t)
s<<-t
ggsave("frequency_by_type.png", plot = t)
}
you could just create a new column indicating wheather it is an outlier or not and map this to the geom_jitter color. I resumed the answer in a smaller example but you should be able to fit this accordingly:
library(ggplot2)
library(viridis)
plot.data <- data.frame(group = c("1","1","1","1","1","2","2","2","2","2"),
value = c(1,5,10,6,3,1,5,10,6,3))
t<-plot.data %>%
mutate(outlier = ifelse(value >9, "YES", "NO")) %>%
ggplot(aes(x = group, y = value, fill = group))+
geom_boxplot()+
geom_jitter(aes(group, value, color = outlier) , size=2, alpha=0.9)+
scale_fill_viridis(discrete = TRUE, alpha = 0.6)
t
library(ggplot2)
# Basic box plot
p <- ggplot(ToothGrowth, aes(x=dose, y=len)) +
geom_boxplot()
p
# Rotate the box plot
p + coord_flip()
# Notched box plot
ggplot(ToothGrowth, aes(x=dose, y=len)) +
geom_boxplot(notch=TRUE)
# Change outlier, color, shape and size
ggplot(ToothGrowth, aes(x=dose, y=len)) +
geom_boxplot(outlier.colour="red", outlier.shape=8,
outlier.size=4)

Add whitespace / increase the space between the X and the Y axis in ggplot [duplicate]

This question already has answers here:
How to make gap between x and y axis and protruded ticks in ggplot2
(4 answers)
Closed 2 years ago.
I am doing some plots for a project where they need to have a specific look. They will need to have some space between the axes lines and the plot panel.
library(ggplot2)
plot_data <- data.frame(X = 1:10, Y = 1:10)
ggplot() + geom_point(data = plot_data, aes(x = X, y = Y)) +
theme(axis.line = element_line(colour = "black", linetype = "solid"))
What I have
I want to add some distance between the X and Y axis of my plot, but without my axes lines also expanding, like they if I use the expand command.
plot_data <- data.frame(X = 1:10, Y = 1:10)
ggplot() + geom_point(data = plot_data, aes(x = X, y = Y)) +
theme(axis.line = element_line(colour = "black", linetype = "solid"))+
scale_x_continuous(name = "X", limits = c(1, 10), expand = c(0.1,0)) +
scale_y_continuous(name = "Y", limits = c(1, 10), expand = c(0.1,0))
What I can do
Is there a fast and reliable way to do this in R?
What i want
Thank you all in advance !
You could achieve this "capping" of the lines with the lemon package. You may use the following code to achieve this:
library(ggplot2)
library(lemon)
### your code
plot_data <- data.frame(X = 1:10, Y = 1:10)
p <- ggplot() + geom_point(data = plot_data, aes(x = X, y = Y)) +
theme(axis.line = element_line(colour = "black", linetype = "solid"))+
scale_x_continuous(name = "X", limits = c(1, 10), expand = c(0.1,0)) +
scale_y_continuous(name = "Y", limits = c(1, 10), expand = c(0.1,0))
### using the lemon package
p + coord_capped_cart(bottom='right', left='none', gap = 0.15)
### mimic the view of your plot
p2 <- p + coord_capped_cart(bottom='right', left='none', gap = 0.15)
p2 + theme(panel.background = element_rect(fill = "white"))
which yields the following picture:
An other option : Deleting the axis lines and making new ones with geom_segment.
plot_data <- data.frame(X = 1:10, Y = 1:10)
library(ggplot2)
ggplot() + geom_point(data = plot_data, aes(x = X, y = Y)) +
theme(axis.line = element_blank(),panel.background =element_blank())+
geom_segment(aes(x=0,y=1,xend=0,yend=10))+
geom_segment(aes(x=1,y=0,xend=10,yend=0))+
scale_x_discrete(limits=c(1,2,3,4,5, 8,10))+
scale_y_discrete(limits=c(1:10))

Pass changed geom from object to other ggplot

I first make a plot
df <- data.frame(x = c(1:40, rep(1:20, 3), 15:40))
p <- ggplot(df, aes(x=x, y = x)) +
stat_density2d(aes(fill='red',alpha=..level..),geom='polygon', show.legend = F)
Then I want to change the geom_density values and use these in another plot.
# build plot
q <- ggplot_build(p)
# Change density
dens <- q$data[[1]]
dens$y <- dens$y - dens$x
Build the other plot using the changed densities, something like this:
# Built another plot
ggplot(df, aes(x=x, y =1)) +
geom_point(alpha = 0.3) +
geom_density2d(dens)
This does not work however is there a way of doing this?
EDIT: doing it when there are multiple groups:
df <- data.frame(x = c(1:40, rep(1:20, 3), 15:40), group = c(rep('A',40), rep('B',60), rep('C',26)))
p <- ggplot(df, aes(x=x, y = x)) +
stat_density2d(aes(fill=group,alpha=..level..),geom='polygon', show.legend = F)
q <- ggplot_build(p)
dens <- q$data[[1]]
dens$y <- dens$y - dens$x
ggplot(df, aes(x=x, y =1)) +
geom_point(aes(col = group), alpha = 0.3) +
geom_polygon(data = dens, aes(x, y, fill = fill, group = piece, alpha = alpha)) +
scale_alpha_identity() +
guides(fill = F, alpha = F)
Results when applied to my own dataset
Although this is exactly what I'm looking for the fill colors seem not to correspond to the initial colors (linked to A, B and C):
Like this? It is possible to plot a transformation of the shapes plotted by geom_density. But that's not quite the same as manipulating the underlying density...
ggplot(df, aes(x=x, y =1)) +
geom_point(alpha = 0.3) +
geom_polygon(data = dens, aes(x, y, fill = fill, group = piece, alpha = alpha)) +
scale_alpha_identity() +
guides(fill = F, alpha = F)
Edit - OP now has multiple groups. We can plot those with the code below, which produces an artistic plot of questionably utility. It does what you propose, but I would suggest it would be more fruitful to transform the underlying data and summarize that, if you are looking for representative output.
ggplot(df, aes(x=x, y =1)) +
geom_point(aes(col = group), alpha = 0.3) +
geom_polygon(data = dens, aes(x, y, fill = group, group = piece, alpha = alpha)) +
scale_alpha_identity() +
guides(fill = F, alpha = F) +
theme_minimal()

Force size aesthetic to scale to given breaks

I am creating several plots in order to create frames for a gif. It is supposed to show growing points over time. (see plot 1 and 2 - the values increase). Using size aesthetic is problematic, because the scaling is done for each plot individually.
I tried to set breaks with scale_size_area() to provide a sequence of absolute values, in order to scale on 'all values' rather than only the values present in each plot. (no success).
Plot 3 shows how the points should be scaled, but this scaling should be achieved in each plot.
library(tidyverse)
df1 <- data.frame(x = letters[1:5], y = 1:5, size2 = 21:25)
ggplot(df1, aes(x, y, size = y)) +
geom_point() +
scale_size_area(breaks = seq(0,25,1))
ggplot(df1, aes(x, y, size = size2)) +
geom_point() +
scale_size_area(breaks = seq(0,25,1))
df2 <- data.frame(x = letters[1:5], y = 1:5, size2 = 21:25) %>% gather(key, value, y:size2)
ggplot(df2, aes(x, value, size = value)) +
geom_point() +
scale_size_area(breaks = seq(0,25,1))
Created on 2019-05-12 by the reprex package (v0.2.1)
Pass lower and upper bound to limits argument in scale_size_area function:
ggplot(df1, aes(x, y, size = y)) +
geom_point() +
labs(
title = "Y on y-axis",
size = NULL
) +
scale_size_area(limits = c(0, 25))
ggplot(df1, aes(x, y, size = size2 )) +
geom_point() +
labs(
title = "size2 on y-axis",
size = NULL
) +
scale_size_area(limits = c(0, 25))
How about this?
library("ggplot2")
df1 <- data.frame(x = letters[1:5],
y = 1:5)
ggplot(data = df1,
aes(x = x,
y = y,
size = y)) +
geom_point() +
scale_size_area(breaks = seq(1,25,1),
limits = c(1, 25))

Resources