Extra spaces between non latin characters in plots in R - r

When I use non-latin (Russian) characters in ggplot legend, the legend line becomes much longer. This example code shows the problem.
test <- data.frame(x = c(1, 2, 3, 4, 5, 6, 7, 8), y = c(1, 4, 9, 16, 25, 36, 25, 16), label = c('green / зеленый ', 'зеленый', 'red', 'white', 'yellow', 'pink', 'красный', 'синий' ))
ggplot(data = test, aes(x= x, y=y)) + geom_point(aes(colour = label), size = 20) + theme(legend.position = "bottom") +
guides(colour = guide_legend(nrow = 2))
Does anyone know the way to cure it? Thanks in advance.

Related

How to add legend to scatter plot in ggplot?

I have assigned a shape and color to each point, and I want to draw the legend according to the group data, but I can't add the legend..
library(datasets)
library(tidyverse)
library(reshape2)
name <- c("S1","S1","S1","S2","S2","S3","S3","S3","S4","S4","S5")
x <- c(1,5,9,8,5,6,7,4,3,6,4)
y <- c(3,8,9,5,7,5,3,8,9,3,4)
Shape <- c(21,21,21,22,22,23,23,23,24,24,25)
Color <- c("red","red","red","blue","blue","green","green","green","purple","purple","black")
df <- data.frame(x,y,name,Shape,Color)
graph1 <- ggplot(df,aes(x,y,fill = Color, shape = Shape))+
geom_point(size = 4)+
scale_shape_identity()+
scale_fill_identity()
graph1
the x and y is the main data. The name is the group. The Shape and Color is the shape and color I assigned for all those point. How to draw a legend according to the group?
I think you are looking for:
ggplot(df, aes(x = x ,y = y, fill = name, shape = name)) +
geom_point(size = 4) +
scale_fill_manual(values = unique(df$Color)) +
scale_shape_manual(values = unique(df$Shape))
You were missing aes parameter color :-)
library(datasets)
library(tidyverse)
library(reshape2)
name <- c('S1', 'S1', 'S1', 'S2', 'S2', 'S3', 'S3', 'S3', 'S4', 'S4', 'S5')
x <- c(1, 5, 9, 8, 5, 6, 7, 4, 3, 6, 4)
y <- c(3, 8, 9, 5, 7, 5, 3, 8, 9, 3, 4)
Shape <- c(21, 21, 21, 22, 22, 23, 23, 23, 24, 24, 25)
Color <- c('red', 'red', 'red', 'blue', 'blue', 'green', 'green', 'green', 'purple', 'purple', 'black')
df <- data.frame(x, y, name, Shape, Color)
graph1 <- ggplot(df, aes(x, y, fill = Color, color = name, shape = Shape)) +
geom_point(size = 4) +
scale_shape_identity() +
scale_fill_identity()
graph1
You will note that using the group (name) as the basis for the legend makes this plot confusing, but in any case, you can add the color param to ensure that your legend is rendered.
if you use Color as the value for the color parameter you get the following:

Change panel width ggplot2

I am creating some plots with ggplot2 and I would like to add stats to it post-hoc. However, I have the issue that the plot ends so close to the margin that I don't have space to add it. Here is a picture:
I would like to draw the stars etc at the right hand side of each plot. So I would like to just have some extra space at the right hand side of each panel. I have been trying to find a command for that but it hasn't been going well...
Here is the code I'm using to plot:
df %>%
group_by(group, animal, day, zone) %>%
summarise(sum_cum = sum(cum_time_sec)) %>%
ggline(x='day', y='sum_cum', color = 'group', fill = ' group', size = 1.1, outlier.shape = NA,
add = c("mean_se"), add.params = list(alpha=0.5), point.size = 4, linetype = 1, facet.by = "zone", ncol = 4)
Thank you!
Without data, it's always more difficult to show a working solution, but we can replicate your plot approximately by doing:
library(ggpubr)
library(dplyr)
df <- data.frame(group = rep(c('A', 'B'), each = 20),
animal = 1, day = rep(1:5, 8), zone = rep(rep(1:4, each = 5), 2),
cum_time_sec = c(5, 10, 11, 10, 8, 10, 9, 8, 7, 8, 40, 35, 37,
39, 41, 5, 4, 3, 4, 5, 4, 4, 4, 5, 3, 10, 6, 7,
8, 6, 40, 45, 44, 45, 49, 4, 3, 4, 2, 1))
p <- df %>%
group_by(group, animal, day, zone) %>%
summarise(sum_cum = sum(cum_time_sec)) %>%
ggline(x='day', y='sum_cum', color = 'group', fill = ' group',
size = 0.5, outlier.shape = NA,
add = c("mean_se"), add.params = list(alpha=0.5),
point.size = 1, linetype = 1, facet.by = "zone", ncol = 4) +
scale_color_manual(values = c('#1064bc', '#afafaf'))
p
To increase panel spacing, we simply use the panel.spacing.x theme element:
p + theme(panel.spacing.x = unit(15, 'mm'))
If you want extra space after the last point, simply change the x axis limits:
p + scale_x_continuous(breaks = 1:5, limits = c(1, 7))
Another option is to use multiple expansions in scale_continuous.
## I am using Allan's carefully produced plot `p`.
## Thanks, Allan +1
p +
scale_x_continuous(breaks = 1:5, expand = expansion(mult = c(0, .4)))

Y axis disappears when I try to use state_smooth() without geom_point()

For some reason, ggplot is omitting the Y axis labels when I try to use stat_smooth() without first calling geom_point(). The hacky solution I came up with was to call geom_point(size = 0, alpha =0), but I'd love (1) to understand what's going on and (2) a more elegant solution.
Minimal reproducible example
library(tidyverse)
# Mock data
set.seed(24)
df <- tibble(x = rep(c(1, 2, 4, 6, 8, 11, 13), 20),
y = round(.3 * x + rnorm(140, 5)),
z = rep(c("A", "B"), 70))
# Original plot
ggplot(df, aes(x, y, color = z)) +
geom_point() +
stat_smooth(method = "lm", formula = "y ~ x", se = FALSE) +
scale_y_continuous(breaks = seq(1, 10, length = 4),
minor_breaks = c(2, 3, 5, 6, 8, 9),
labels = c("1. Fully disaproves", "4", "7",
"10. Fully approves"))
# The plot I actually want (except the Y axis labels disappear)
ggplot(df, aes(x, y, color = z)) +
stat_smooth(method = "lm", formula = "y ~ x", se = FALSE) +
scale_y_continuous(breaks = seq(1, 10, length = 4),
minor_breaks = c(2, 3, 5, 6, 8, 9),
labels = c("1. Fully disaproves", "4", "7",
"10. Fully approves"))
# Hacky solution
ggplot(df, aes(x, y, color = z)) +
geom_point(size = 0, alpha = 0) +
stat_smooth(method = "lm", formula = "y ~ x", se = FALSE) +
scale_y_continuous(breaks = seq(1, 10, length = 4),
minor_breaks = c(2, 3, 5, 6, 8, 9),
labels = c("1. Fully disaproves", "4", "7",
"10. Fully approves"))
Output
PS: I'm totally blind–obviously, I can't see the output. There's a chance that the plots don't show at all what I hope they do. Hopefully, You'll be able to figure out what I want from the code.
The issue is that when you use stat_smooth only, the range of the plotted data is different from when you also add the geom_point. As by default ggplot2 sets the limits of the scale according to the range of the data you get a scale which ranges from 5 to 9. Because of this only one of your breaks (i.e. 7). will show up, while all other breaks are omitted as they fall out of the limits. This said, to achieve your desired result you have to set the limits:
library(ggplot2)
library(tibble)
# Mock data
set.seed(24)
df <- tibble(x = rep(c(1, 2, 4, 6, 8, 11, 13), 20),
y = round(.3 * x + rnorm(140, 5)),
z = rep(c("A", "B"), 70))
# The plot I actually want (except the Y axis labels disappear)
ggplot(df, aes(x, y, color = z)) +
stat_smooth(method = "lm", formula = "y ~ x", se = FALSE) +
scale_y_continuous(breaks = seq(1, 10, length = 4),
minor_breaks = c(2, 3, 5, 6, 8, 9),
labels = c("1. Fully disaproves", "4", "7",
"10. Fully approves"),
limits = c(1, 10))

ggplot time series: messed up x axis - 2

This is modified version of this question.
I need to create time series plot for 2 lines for the following data:
# Creating data set
year <- c(rep(2018,4), rep(2019,4), rep(2020,4))
month_1 <- c(2, 3, 7, 8, 6, 10, 11, 12, 5, 7, 8, 12)
avg_dlt_calc <- c(10, 20, 11, 21, 13, 7, 10, 15, 9, 14, 16, 32)
avg_dlt_standard <- c(rep(9,12))
data_to_plot <- data.frame(cbind(year,month_1,avg_dlt_calc,avg_dlt_standard ))
data_to_plot$month_1 <- factor(data_to_plot$month_1, levels=unique(data_to_plot$month_1))
ggplot(data_to_plot,aes(x = as.factor(month_1))) +
geom_line(aes(y = avg_dlt_calc, group = year, colour = "DLT Calculated"), size = 0.5) +
geom_line(aes(y = avg_dlt_standard, group = year, colour = "DLT standard"), size = 0.5) +
geom_point(aes(y = avg_dlt_calc, colour = "DLT Calculated")) +
scale_x_discrete(name = "months", limits = data_to_plot$month_1) +
facet_grid(~year, scales = "free")+
scale_color_manual(name="",
labels = c("DLT Calculated",
"DLT standard"),
values = c( "blue",
"red")) +
theme(legend.position="top",
legend.text = element_text(size = 8))
s = data_to_plot$month_1) +
facet_grid(~year, scales = "free")+
But x-axis looks wrong:
If to plot data without this line:
data_to_plot$month_1 <- factor(data_to_plot$month_1, levels=unique(data_to_plot$month_1))
Then x-axis will still be messy:
I am setting limits for x-axis, but looks like it is not working.
How can I fix it?
I've skipped some lines and features of your plot, but in essence, this is what needs to be changed:
ggplot(data_to_plot, aes(x=month_1))+ # no as.factor
geom_point(aes(y=avg_dlt_calc)) +
geom_line(aes(y=avg_dlt_calc)) +
geom_line(aes(y=avg_dlt_standard), colour='red') +
scale_x_continuous(breaks=1:12, limits=c(1,2)) + # do *not* use scale_x_discrete,
# your x-axis is *continuous*; use breaks-argument to set the ticks.
# note, limits should only have 2 values - upper and lower limit.
facet_grid(~year)
In your code, you used limits = data_to_plot$month_1, but ggplot2 only used the 2 first elements of month_1 - it did not interpret it as a set of acceptable values.

How to add subtext to axes in ggplot2 R

For the main y-axis and x-axis, I have generic titles like "Tank's Ratio" and "Counts". I want a second line of label where I specify the ratio and counts. eg. Just below "Tank's Ratio" I want "# in water/# in sand" in a smaller font but along the y-axis. Similarly for the x-axis.
Here is the basic code
data <- data.frame(set = c(1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 4, 4), density = c(1, 3, 3, 1, 3, 1, 1, 1, 3, 3, 1, 3), counts = c(100, 2, 3, 76, 33, 12, 44, 13, 54, 36, 65, 1), ratio = c(1, 2, 3, 4, 1, 2, 3, 4, 5, 6, 90, 1))
library(ggplot2)
ggplot(data, aes(x = counts, y = ratio)) +
geom_point() +
ylab("Tank's Ratio") +
xlab("Counts")
You can add x and main titles.
EDIT: This is ridiculously slooow!
#library(extrafont)
#loadfonts(dev="win")
library(tidyverse)
data %>%
ggplot(aes(x=counts, y=ratio)) + geom_point() +
labs(y=expression(atop(bold("Tank's Ratio"),atop(italic("#in water #in sand")))))+
theme_minimal()+
theme(axis.title.y = element_text(size=15,family="Comic Sans MS"))
ORIGINAL:
library(tidyverse)
data %>%
ggplot(aes(x=counts, y=ratio)) + geom_point() +
labs(y="Tank's Ratio \n #in Water#in sand")
It's not the most elegant solution, but hope it helps:
library(ggplot2)
library(gridExtra)
library(grid)
First, create plot without ylab:
g <- ggplot(data, aes(x = counts, y = ratio)) +
geom_point() +
ylab("") +
xlab("Counts")
Then add subtitle for both axis:
g2 <- grid.arrange(g,
bottom = textGrob("in water/ # in sand",
x = 0.55, y = 1, gp = gpar(fontsize = 9)),
left = textGrob("in water/ # in sand", rot = 90,
x = 1.5, gp = gpar(fontsize = 9)))
And finally, add description of y-axis
grid.arrange(g2,
left = textGrob("Tank's Ratio", rot = 90,
x = 1.7, gp = gpar(fontsize = 12)))
You could use the following code, defining the margins, the axis titles and sub-titles yourself:
We use theme to increase the bottom and left margin, and to suppress the automatically generated axis titles.
We use annotate to generate the text that serves as axis title and sub-title, if necessary, the text is rotated.
We generate the plot, turn it in a grob, and with this grob we can turn of clipping, and show the plot.
g1 <- ggplot(data = data, aes(x = counts, y = ratio, group = 1)) +
geom_point() +
## increase margin size for left and bottom and
## remove the axis titles
theme(plot.margin = unit(c(1, 1, 4, 4), "lines"),
axis.title.y = element_blank(),
axis.title.x = element_blank() ) +
## define the plotting area to NOT include the annotations
coord_cartesian(xlim = c(0, 100), ylim= c(0, 100), expand = FALSE) +
## annotate y axis
annotate(geom = "text", x = -9, y = 50, label = "Tank's Ratio", angle = 90, size = 5) +
annotate(geom = "text", x = -5, y = 50, label = "#in water/#in sand", angle = 90, size = 4) +
## annotate x axis
annotate(geom = "text", x = 50, y = -5, label = "Counts", size = 5) +
annotate(geom = "text", x = 50, y = -9, label = "#in water/#in sand", size = 4)
## turn off clipping for axis extra labels
g2 <- ggplot_gtable(ggplot_build(g1))
g2$layout$clip[g2$layout$name == "panel"] <- "off"
grid::grid.draw(g2)
This yields the following picture:
Please let me know whether this is what you want.

Resources