columns are not aligned with the data in ggplot geom_col - r

plotting some data to a figure with numerical data, one would expect the column border to line up with the grid. However, when plotting this data, you can see that there are some that line up correctly (10, 5), but others don't (2, 1).
Is this a bug or a feature?
Reproducible example
library(tidyverse, scales)
The data
x1 <- c("a", "b", "c", "d", "e")
y1 <- c(1, 10, 2, 1, 5)
xy <- data.frame(x1, y1)
The plot
xy %>%
ggplot(aes(x = fct_reorder(x1, desc(y1)),
y = y1)) +
geom_col() +
geom_text(aes(label = y1), vjust = 1.5, colour = "white") # to show the numbers
Some experiments
Correct
xy %>%
ggplot(aes(x = fct_reorder(x1, desc(y1)),
y = y1)) +
geom_col() +
scale_y_continuous(minor_breaks = seq(0, 10, .5)) +
# scale_y_continuous(labels = scales::number_format(accuracy = .5)) +
geom_text(aes(label = y), vjust = 1.5, colour = "white")
But then
Incorrect
xy %>%
ggplot(aes(x = fct_reorder(x1, desc(y1)),
y = y1)) +
geom_col() +
scale_y_continuous(minor_breaks = seq(0, 10, .5)) +
scale_y_continuous(labels = scales::number_format(accuracy = .5)) +
geom_text(aes(label = y), vjust = 1.5, colour = "white")
Also incorrect
xy %>%
ggplot(aes(x = fct_reorder(x1, desc(y1)),
y = y1)) +
geom_col() +
scale_y_continuous(minor_breaks = seq(0, 10, 1),
labels = scales::number_format(accuracy = 1)) +
geom_text(aes(label = y1), vjust = 1.5, colour = "white")

That 2 in yaxis is 2.5 and near 1 is 1.25 not 1.
xy %>%
ggplot(aes(x = fct_reorder(x1, desc(y1)),
y = y1)) +
geom_col() +
scale_y_continuous(breaks = seq(0,10,2)) +
geom_text(aes(label = y1), vjust = 1.5, colour = "white")
xy %>%
ggplot(aes(x = fct_reorder(x1, desc(y1)),
y = y1)) +
geom_col()
I don't know why you add accuracy = 1 but take a look at plot below.
xy %>%
ggplot(aes(x = fct_reorder(x1, desc(y1)),
y = y1)) +
geom_col() +
scale_y_continuous(breaks = seq(0,10,2))

This is a rounding error caused by your scales_y_continuous call. Use
ggplot(xy,aes(x = fct_reorder(x1, desc(y1)),
y = y1)) +
geom_col() +
scale_y_continuous(breaks=c(0,2,5,8,10)) +
geom_text(aes(label = y1), vjust = 1.5, colour = "white")
To get what you want.

Related

Labeling pie charts using ggplot2

I have this code:
as_tibble(earlyCiliated[[]]) %>%
ggplot(aes(x="", y=Phase, fill=Phase)) + geom_col() +
coord_polar("y", start=0) +
geom_text(aes(label = paste0(Phase, "%")))
and my output looks like this:
What am I doing wrong that's causing the labels to all be on top of each other?
I can't completely recreate your plot because I do not have your data. That being said, you can try this:
install.packages("ggrepel")
library(ggrepel)
as_tibble(earlyCiliated[[]]) %>%
ggplot(aes(x="", y=Phase, fill=Phase)) + geom_col() +
coord_polar("y", start=0) +
geom_label_repel(data = earlyCiliated[[]],
aes(y = Phase, label = paste0(Phase, "%")),
size = 4.5, nudge_x = 1, show.legend = FALSE)
This is what it will look like (using other data because none was provided)
library(ggplot2)
library(ggrepel)
library(tidyverse)
df <- data.frame(value = c(15, 25, 32, 28),
group = paste0("G", 1:4))
# Get the positions
df2 <- df %>%
mutate(csum = rev(cumsum(rev(value))),
pos = value/2 + lead(csum, 1),
pos = if_else(is.na(pos), value/2, pos))
ggplot(df, aes(x = "" , y = value, fill = fct_inorder(group))) +
geom_col(width = 1, color = 1) +
coord_polar(theta = "y") +
scale_fill_brewer(palette = "Pastel1") +
geom_label_repel(data = df2,
aes(y = pos, label = paste0(value, "%")),
size = 4.5, nudge_x = 1, show.legend = FALSE) +
guides(fill = guide_legend(title = "Group")) +
theme_void()

Plot coloured boxes around axis label

Consider this simple example
library(tidyverse)
tibble(x = as.factor(c('good', 'neutral', 'bad')),
y = as.factor(c('bad', 'neutral', 'bad'))) %>%
ggplot(aes(x = x, y = y)) + geom_point()
I would like to put the x labels (good, neutral, bad) in different colored boxes. For instance, good (on both the x and y axis) would be surrounded on a small green box, and so on.
Can I do that in ggplot2?
Like this?
tibble(x = as.factor(c('good', 'neutral', 'bad')),
y = as.factor(c('bad', 'neutral', 'bad'))) %>%
ggplot(aes(x = x, y = y)) +
geom_point() +
theme(axis.text.x = element_text(color = c('red', 'blue', 'green')))
Your Plot:
EDIT
An alternate pretty Ghetto solution using grid
tibble(x = as.factor(c('good', 'neutral', 'bad')),
y = as.factor(c('bad', 'neutral', 'bad'))) %>%
ggplot(aes(x = x, y = y)) +
geom_point()
grid::grid.polygon(x = c(.3,.3,.25,.25), y = c(.07,.04,.04,.07),gp = gpar(col = 'green', fill = 'green', alpha = .5))
grid::grid.polygon(x = c(.525,.525,.575,.575), y = c(.07,.04,.04,.07),gp = gpar(col = 'red', fill = 'red', alpha = .5))
grid::grid.polygon(x = c(.79,.79,.86,.86), y = c(.07,.04,.04,.07),gp = gpar(col = 'blue', fill = 'blue', alpha = .5))
Solution using geom_label outside the plot area:
ggplot(data, aes(x, y)) +
geom_point() +
geom_label(aes(0.3, y, label = y, fill = y), hjust = 0) +
geom_label(aes(x, 0.45, label = x, fill = x)) +
theme_minimal() +
theme(
axis.text = element_blank(),
axis.ticks = element_blank(),
legend.position = "none"
) +
coord_cartesian(xlim = c(1, 3), ylim = c(1, 2), clip = "off")
Another solution
You should create geom_rect with borders, but without fill and plot them outside the plot area (using coord_cartesian):
library(tidyverse)
data <- tibble(
x = as.factor(c('good', 'neutral', 'bad')),
y = as.factor(c('bad', 'neutral', 'bad'))
)
ggplot(data, aes(x, y)) +
geom_point() +
# put rects on y-axis
geom_rect(aes(xmin = 0.1, xmax = 0.45, color = y,
ymin = as.numeric(y) - 0.1, ymax = as.numeric(y) + 0.1),
fill = NA, size = 3) +
# put rects on x-axis
geom_rect(aes(ymin = 0.3, ymax = 0.4, color = x,
xmin = as.numeric(x) - 0.15, xmax = as.numeric(x) + 0.15),
fill = NA, size = 3) +
# Here it's important to specify that your axis goes from 1 to max number of levels
coord_cartesian(xlim = c(1, 3), ylim = c(1, 2), clip = "off")
Another approach
Create a vector of colors and pass them into axis.text.x() option of theme().
# data
x = as.factor(c('good', 'neutral', 'bad'))
y = as.factor(c('bad', 'neutral', 'bad'))
df<- data.frame(x,y)
# create a vector of colors
mycolors<- c("red","blue","green")
library(ggplot2)
ggplot(df, aes(x = x, y=y))+
geom_point()+
theme(axis.text.x = element_text(colour = mycolors))
One approach could be this:
tibble(x = as.factor(c('good', 'neutral', 'bad')),
y = as.factor(c('bad', 'neutral', 'bad'))) %>%
ggplot(aes(x = x, y = y)) + geom_point()+
geom_rect(aes(xmin=0.5, xmax=1.5, ymin=-Inf, ymax=Inf), fill="red", alpha=0.1)+
geom_rect(aes(xmin=1.5, xmax=2.5, ymin=-Inf, ymax=Inf), fill="yellow", alpha=0.1)+
geom_rect(aes(xmin=2.5, xmax=3.5, ymin=-Inf, ymax=Inf), fill="green", alpha=0.1)
With geom_rect() you can add colored backgrounds:

How to customize a boxplot legend indicating mean, outliers, median, etc?

I have a boxplot and by my supervisor's advice I have to indicate the mean, outliers and median in the legend, like this image:
How can I do this using ggplot2?
library(ggplot2)
A <- 1:20
DF <- data.frame(A)
ggplot(data = DF) +
geom_boxplot(aes(x = "", y = A))
There is no straightforward way. But you could make a custom legend using another plot:
p <- ggplot(mtcars) +
geom_boxplot(aes(x = factor(cyl), y = mpg))
d1 <- data.frame(x = 1, y = c(1:1000, 1502))
d2 <- data.frame(
y = c(boxplot.stats(d1$y)$stats, 1502),
x = 1,
label = c('min', '1st quartile', 'median', '3rd quartile', 'max', 'outlier')
)
leg <- ggplot(d1, aes(x, y)) + geom_boxplot(width = 0.2) +
geom_text(aes(x = 1.15, label = label), d2, hjust = 0) +
xlim(0.9, 1.5) +
theme_void() + theme(panel.background = element_rect(fill = 'white', color = 1))
p + annotation_custom(ggplotGrob(leg), xmin = 3, xmax = 3.5, ymin = 25, ymax = 35)

Labeling a point by giving its x and y axes on geom_histogram

How to show the point (x=0, y=1500) with a text label next to it on the following histogram?
ggplot(ds_visits, aes(x = patientsInService)) +
geom_histogram(stat = "count", col = "black", fill = "white") +
theme_bw() +
labs(x = "Patients in service", y = "Cases") +
scale_x_discrete(limits = seq(0, 5, 1))
You have to create dummy data.frame for point data:
pointData <- data.frame(X = 0, Y = 1500)
Plot it with with two additional gems (geom_point and geom_text):
ggplot(ds_visits, aes(patientsInService)) +
geom_histogram(stat = "count", col = "black", fill = "white") +
geom_point(data = pointData, aes(X , Y)) +
geom_text(data = pointData, aes(X + 1 , Y + 10, label = "My Text"))
In geom_text I'm changing coordinates a little bit not to overlap text with point.

Create a RDA biplot using extracted RDA results and merge to graphs

Currently trying to use extracted data to create two seperate RDA biplots. Using the code that follows:
p <- ggplot()
p + geom_vline(x=0,colour="grey50") +
geom_hline(y=0,colour="grey50") +
geom_text(data = PHYTOPLANKTON_coordinates_scaling_2, aes(x = RDA1, y = RDA2,
label=rownames(PHYTOPLANKTON_coordinates_scaling_2)), angle=45, size=3,
colour = 'blue') +
geom_segment(data = WQ_coordinates_scaling_2, aes(x = 0, y = 0,
xend = RDA1, yend = RDA2), size = 0.5, colour = 'red') +
geom_text(WQ_coordinates_scaling_2, aes(x = RDA1, y = RDA2,
label = rownames(WQ_coordinates_scaling_2)), size = 5, angle = 45,
vjust = 1, colour = 'violet') +
theme_bw()
This results in:
Error: unexpected '=' in: " + geom_text(data =
PHYTOPLANKTON_coordinates_scaling_2, aes(x = RDA1, y = RDA2,
+ label="
+ colour = 'blue') Error: unexpected ')' in " + colour =
'blue')"
set.seed(123)
# Generate toy data
n <- 20
PHYTOPLANKTON_coordinates_scaling_2 <-
data.frame(RDA1 = rnorm(n), RDA2 = rnorm(n))
rownames(PHYTOPLANKTON_coordinates_scaling_2) <- LETTERS[1:n]
k <- 4
WQ_coordinates_scaling_2 <-
data.frame(RDA1 = rnorm(k), RDA2 = rnorm(k))
rownames(WQ_coordinates_scaling_2) <- paste0("V",1:k)
# Plot data
library(ggplot2)
p <- ggplot()
p + geom_vline(xintercept=0,colour="grey50") +
geom_hline(yintercept=0,colour="grey50") +
geom_text(data=PHYTOPLANKTON_coordinates_scaling_2, aes(x=RDA1, y=RDA2,
label=rownames(PHYTOPLANKTON_coordinates_scaling_2)), angle=45, size=3,
colour = 'blue') +
geom_segment(data=WQ_coordinates_scaling_2, aes(x = 0, y = 0,
xend = RDA1, yend = RDA2), size = 0.5, colour = 'red') +
geom_text(data=WQ_coordinates_scaling_2, aes(x=RDA1, y=RDA2,
label = rownames(WQ_coordinates_scaling_2)), size = 5, angle = 45,
vjust = 1, colour = 'violet') +
theme_bw()

Resources