Let's say I want to make a histogram
So I use the following code
v100<-c(runif(100))
v100
library(ggplot2)
private_plot<-ggplot()+aes(v100)+geom_histogram(binwidth = (0.1),boundary=0
)+scale_x_continuous(breaks=seq(0,1,0.1), lim=c(0,1))
private_plot
How do I separate my columns so that the whole thing is more pleasing to the eye?
I tried this but it somehow doesn't work:
Adding space between bars in ggplot2
Thanks
You could set the line color of the histogram bars with the col parameter, and the filling color with the fill parameter. This is not really adding space between the bars, but it makes them visually distinct.
library(ggplot2)
set.seed(9876)
v100<-c(runif(100))
### use "col="grey" to set the line color
ggplot() +
aes(v100) +
geom_histogram(binwidth = 0.1, fill="black", col="grey") +
scale_x_continuous(breaks = seq(0,1,0.1), lim = c(0,1))
Yielding this graph:
Please let me know whether this is what you want.
If you want to increase the space for e.g. to indicate that values are discrete, one thing to do is to plot your histogram as a bar plot. In that case, you have to summarize the data yourself, and use geom_col() instead of geom_histogram(). If you want to increase the space further, you can use the width parameter.
library(tidyverse)
lambda <- 1:6
pois_bar <-
map(lambda, ~rpois(1e5, .x)) %>%
set_names(lambda) %>%
as_tibble() %>%
gather(lambda, value, convert = TRUE) %>%
count(lambda, value)
pois_bar %>%
ggplot() +
aes(x = value, y = n) +
geom_col(width = .5) +
facet_wrap(~lambda, scales = "free", labeller = "label_both")
Just use color and fill options to distinguish between the body and border of bins:
library(ggplot2)
set.seed(1234)
df <- data.frame(sex=factor(rep(c("F", "M"), each=200)),
weight=round(c(rnorm(200, mean=55, sd=5), rnorm(200, mean=65, sd=5))))
ggplot(df, aes(x=weight)) +
geom_histogram(color="black", fill="white")
In cases where you are creating a "histogram" over a range of integers, you could use:
ggplot(data) + geom_bar(aes(x = value, y = ..count..))
I just came across this issue. My solution was to add vertical lines at the points separating my bins. I use "theme_classic" and have a white background. I set my bins to break at 10, 20, 30, etc. So I just added 9 vertical lines with:
geom_vline(xintercept=10, linetype="solid", color = "white", size=2)+
geom_vline(xintercept=20, linetype="solid", color = "white", size=2)+
etc
A silly hack, but it works.
Related
I intended to color lines in pink, and points in yellow. I don't want to use colour argument in respective geom(), I want to use scale to change colour.
p3 <- ggplot(dfcc,aes(x = yr, y = mean)) +
geom_line(aes(color = '')) +
geom_point(aes(color = ''))
p3 + scale_colour_manual(values =c('pink', 'yellow'))
This gives this plot, both lines and points are not in the right colours.
Hence, I have two questions
can I use "scale_colour_manual" to change the line and point colors in one go?
if having multiple geoms and multiple scales, how does the system know which scale applies to which geom?
Any help and explanation would be much appreciated!
Use package ggnewscale.
set.seed(2022)
df1 <- data.frame(x = 1:20, y = cumsum(rnorm(20, 2)))
library(ggplot2)
ggplot(df1, aes(x, y)) +
geom_line(color = "pink", linewidth = 2) +
ggnewscale::new_scale_color() +
geom_point(color = "yellow", size = 3) +
theme_classic()
Created on 2022-12-25 with reprex v2.0.2
This is my dataframe:
df = data.frame(info=1:30, type=c(replicate(5,'A'), replicate(5,'B')), group= c(replicate(10,'D1'), replicate(10,'D2'), replicate(10,'D3')))
I want to make a jitter plot of my data distinguished by group (X-label) and type (colour):
ggplot()+
theme(panel.background=element_rect(colour="grey", size=0.2, fill='grey100'))+
geom_jitter(data=df, aes(x=group, y=info, color=type, shape=type), position=position_dodge(0.2), cex=2)+
scale_shape_manual(values=c(17,15,19))+
scale_color_manual(values=c(A="mediumvioletred", B="blue"))
How can I reduce the distance between the X-labels (D1, D2, D3) in the representation?
P.D. I want to do it even if I left a blank space in the graphic
Here are a few options.
# Setting up the plot
library(ggplot2)
df <- data.frame(
info=1:30,
type=c(replicate(5,'A'), replicate(5,'B')),
group= c(replicate(10,'D1'), replicate(10,'D2'), replicate(10,'D3'))
)
p <- ggplot(df, aes(group, info, colour = type, shape = type))
Option 1: increase the dodge distance. This won't put the labels closer, but it makes better use of the space available so that the labels appear less isolated.
p +
geom_point(position = position_dodge(width = 0.9))
Option 2: Expand the x-axis. Increasing the expansion factor from the default 0.5 to >0.5 increases the space at the ends of the axis, putting the labels closer.
p +
geom_point(position = position_dodge(0.2)) +
scale_x_discrete(expand = c(2, 0))
Option 3: change the aspect ratio. Depending on the plotting window size, this also visually puts the x-axis labels closer together.
p +
geom_point(position = position_dodge(0.2)) +
theme(aspect.ratio = 2)
Created on 2021-06-25 by the reprex package (v1.0.0)
Try adding coord_fixed(ratio = 0.2) and play around with the ratio.
ggplot()+
theme(panel.background=element_rect(colour="grey", size=0.2, fill='grey100'))+
geom_jitter(data=df, aes(x=group, y=info, color=type, shape=type), position=position_dodge(0.2))+
scale_shape_manual(values=c(17,15,19))+
scale_color_manual(values=c(A="mediumvioletred", B="blue")) + coord_fixed(ratio = 0.2)
The simplest solution is to resize the plot. For example if you follow your command with ggsave("my_plot.pdf", width = 3, height = 4.5) it looks like this:
Or in an Rmd file you can control the dimensions by various means: see this link.
I want to draw a dot plot with horizontal lines by groups.
The df object store the points and the df.line object stores the line I want to add to the dot plot. The horizontal lines are not the mean/median value of points, they are some standards I want to show in this figure.
I tried gome_hline, geom_line, geom_errorbar, and stat_summary. but none of them work as I want.
Could anyone teach me how to do it?
library(ggplot2)
library(tidytext)
set.seed(42)
df=data.frame(site=c(rep("a",5),rep("b",5),rep("c",5)),
sample=c(1:5,1:5,1:5),
value=c(runif(5, min=0.54, max=0.56),runif(5, min=0.52, max=0.6),runif(5,
min=0.3, max=0.4)),
condition=c(rep("c1",5),rep("c2",5),rep("c2",5)))
df.line=data.frame(site=c("a","b","c"),standard=c(0.55,0.4,0.53))
ggplot(df)+
geom_point(aes(x=tidytext::reorder_within(site,value,condition,fun=mean),
y=value))+
facet_grid(~condition,space="free_x",scales = "free_x")+
scale_x_reordered()
First, merge df and df.line together. Next, move the main aes() call to ggplot so it can be used later. Then use stat_summary:
library(dplyr)
merge(df,df.line) %>%
ggplot(aes(x=tidytext::reorder_within(site,value,condition,fun=mean),
y=value))+
geom_point()+
stat_summary(aes(y = standard, ymax = after_stat(y), ymin = after_stat(y)),
fun = mean, geom = "errorbar", color = "red", width = 0.3) +
facet_grid(~condition,space="free_x",scales = "free_x")+
scale_x_reordered()
I have created a chart with ggplot.
I have set the width of each bar, but I also want to set the spacing between the bars to a certain value (I want to reduce the spacing marked in red to 0.1, for example)? I know there are options like position_dodge, but that does not seem to work in combination with coord_flip().
In this related post it was suggested to use theme(aspect.ratio = .2), but this does not allow to additionally set the specific width of the bars.
Are there any suggestions to achieve this?
Code:
library(ggplot2)
set.seed(0)
numbers <- runif(5, 0, 10)
names <- LETTERS[seq(1, 5)]
df <- cbind.data.frame(names, numbers)
ggplot(data = df, aes(x = names, y = numbers)) +
geom_bar(stat = "identity", fill = "blue", width = 0.30) +
coord_flip()
I think the solution is in the combination of
the width argument of geom_bar() (which fills the space reserved for a bar)
and the aspect ratio argument of theme(), which squeezes the plot vertically, leading to 'small' bars.
With the following code:
library(ggplot2)
## your data
set.seed(0)
numbers <- runif(5, 0, 10)
names <- LETTERS[seq(1, 5)]
df <- cbind.data.frame(names, numbers) ## corrected args
ggplot(data = df, aes(x = names, y = numbers)) +
geom_bar(stat="identity",
fill = "blue",
width=0.9) + ### increased
theme(aspect.ratio = .2) + ### aspect ratio added
coord_flip()
you get the following graph:
I personally prefer to use the ggstance package to avoid messing around with coord_flip. you need to switch your x and y
library(ggplot2)
library(ggstance)
ggplot(df, aes(x = numbers, y = names)) +
geom_colh(fill = "blue", width = 0.9)
I have a bit of a coding issue. I have a MWE below:
df <- data.frame(year=seq(1961,2013,1), group1=rnorm(53), group2=rnorm(53))
p <- ggplot(df, aes(x=year)) +
geom_line(aes(y=group1, linetype="group1")) +
geom_line(aes(y=group2, linetype="group2"))
p1 <- ggplot(df, aes(x=year)) +
geom_line(aes(y=group1, linetype="group1"), lwd=1.5) +
geom_line(aes(y=group2, linetype="group2"))
p produces a very standard looking graph with no issues:
However, when I try to change the linewidth in p1, of one of the geom_line, this distorts the legend as such:
The dotted aspect of the line remains the same but the lined segment is being affected by the lwd=1.5 from the first line.
Is there an error/shortcoming in my approach to this problem or a larger issue at play here?
If you want a nice legend with different linetypes and linewidths then you should convert your data to long format, map group on both linetype and lwd aestehtics and set the lwd manually using scale_size_manual.
library(ggplot2)
library(dplyr)
library(tidyr)
df <- data.frame(year=seq(1961,2013,1), group1=rnorm(53), group2=rnorm(53))
df %>%
pivot_longer(-year, names_to = "group") %>%
ggplot(aes(x=year)) +
geom_line(aes(y=value, linetype = group, lwd = group)) +
scale_size_manual(values = c(1.5, .5))
Created on 2020-05-27 by the reprex package (v0.3.0)