Is it possible to add horizontal lines from 0 to the points on the plot shown below?
This is the code thus far:
ggplot(data, aes(x=change, y=industry, color=geo)) + geom_point() +
scale_x_continuous(labels = scales::comma) + geom_vline(xintercept = 0)
Alternatively, I could use geom_bar() but I have been unsure how to show both London and the UK without them summing together.
tl;dr you can use geom_bar() with position="stack", stat="identity". Or you can use geom_segment().
set up data
dd <- expand.grid(industry=c("property",
"manufacturing",
"other"),
geo=c("London","UK"))
set.seed(101)
dd$change <- runif(6,min=-30,max=30)
This is how you could do it with geom_bar
library(ggplot2)
ggplot(dd,aes(x=industry,y=change,
fill=geo))+
geom_bar(stat="identity",
position="dodge")+
coord_flip()
Or with geom_segment():
ggplot(dd,aes(x=change,y=industry,
colour=geo))+
geom_point(size=2)+
geom_segment(aes(xend=0,yend=industry))
You might want to consider manually dodging the position in the second case, but position_dodge in ggplot can only dodge horizontally, so you should either switch x and y and use coord_flip(), or use position_dodgev from the ggstance package.
Related
I basically have a very simple question, how can I make bar charts shorter? If I search for it on the web I can only find "width", but this is not what I want. I want to make the lenght of the bars shorter.
library(ggplot2)
# data
data <- data.frame(
name=c("A","B","C","D","E") ,
value=c(3,12,5,18,45)
)
# bar chart
ggplot(data, aes(x=name, y=value)) +
geom_bar(stat = "identity", width=0.8) +
coord_flip()
I basically just want that the lenght of the bar goes up to like around 20, so somehow just half the length..
I think you mean how do you make the bars visibly shorter on the page without affecting their numerical representation. Perhaps you just need to set the axis limits?
If your plot looks like this...
p <- ggplot(data, aes(x=name, y=value)) +
geom_bar(stat = "identity", width=0.8) +
coord_flip()
p
Then you can just do this...
p + scale_y_continuous(limits = c(0, 2 * max(data$value)))
Created on 2020-11-10 by the reprex package (v0.3.0)
I'm creating a plot with ggplot that uses colored points, vertical lines, and horizontal lines to display the data. Ideally, I'd like to use two different color or linetype scales for the geom_vline and geom_hline layers, but ggplot discourages/disallows multiple variables mapped to the same aesthetic.
# Create example data
library(tidyverse)
library(lubridate)
set.seed(1234)
example.df <- data_frame(dt = seq(ymd("2016-01-01"), ymd("2016-12-31"), by="1 day"),
value = rnorm(366),
grp = sample(LETTERS[1:3], 366, replace=TRUE))
date.lines <- data_frame(dt = ymd(c("2016-04-01", "2016-10-31")),
dt.label = c("April Fools'", "Halloween"))
value.lines <- data_frame(value = c(-1, 1),
value.label = c("Threshold 1", "Threshold 2"))
If I set linetype aesthetics for both geom_*lines, they get put in the
linetype legend together, which doesn't necessarily make logical sense
ggplot(example.df, aes(x=dt, y=value, colour=grp)) +
geom_hline(data=value.lines, aes(yintercept=value, linetype=value.label)) +
geom_vline(data=date.lines, aes(xintercept=as.numeric(dt), linetype=dt.label)) +
geom_point(size=1) +
scale_x_date() +
theme_minimal()
Alternatively, I could set one of the lines to use a colour aesthetic,
but then that again puts the legend lines in an illogical legend
grouping
ggplot(example.df, aes(x=dt, y=value, colour=grp)) +
geom_hline(data=value.lines, aes(yintercept=value, colour=value.label)) +
geom_vline(data=date.lines, aes(xintercept=as.numeric(dt), linetype=dt.label)) +
geom_point(size=1) +
scale_x_date() +
theme_minimal()
The only partial solution I've found is to use a fill aesthetic instead
of colour in geom_pointand setting shape=21 to use a fillable shape,
but that forces a black border around the points. I can get rid of the
border by manually setting color="white, but then the white border
covers up points. If I set colour=NA, no points are plotted.
ggplot(example.df, aes(x=dt, y=value, fill=grp)) +
geom_hline(data=value.lines, aes(yintercept=value, colour=value.label)) +
geom_vline(data=date.lines, aes(xintercept=as.numeric(dt), linetype=dt.label)) +
geom_point(shape=21, size=2, colour="white") +
scale_x_date() +
theme_minimal()
This might be a case where ggplot's "you can't have two variables mapped
to the same aesthetic" rule can/should be broken, but I can't figure out clean way around it. Using fill with geom_point shows the most promise, but there's no way to remove the point borders.
Any ideas for plotting two different color or linetype aesthetics here?
See plot here:
(from here)
How do I reproduce both the upper and lower portion of the barplot using ggplot2?
For example, I can produce the upper portion with
ggplot(data.frame(x=rnorm(1000, 5)), aes(x=x)) + geom_bar() + scale_y_reverse()
However now if I add any other geom_, such as another geom_bar() the scale for y is reversed. Is it possible to apply the scale_y_reverse() to only a specific geom_?
Another option is to make two separate plots and combine them with arrangeGrob from the gridExtra package. After playing with the plot margins, you can arrive at something that looks decent.
library(gridExtra)
library(ggplot2)
set.seed(100)
p2 <- ggplot(data.frame(x=rnorm(1000, 5)), aes(x=x)) + geom_bar() + theme(plot.margin=unit(c(0,0,0,0), 'lines'))
p1 <- p2 + scale_y_reverse() +
theme(plot.margin=unit(c(0, 0, -.8, 0), 'lines'), axis.title.x=element_blank(),
axis.text.x=element_blank(), axis.ticks.x=element_blank())
p <- arrangeGrob(p1, p2)
print(p)
ggplot only like to have one y-axis scale. The easiest thing would be to basically reshape your data yourself. Here we can use geom_rect to draw the data where ever we like and we can condition it on group time. Here's an example
#sample data
dd<-data.frame(
year=rep(2000:2014, 2),
group=rep(letters[1:2], each=15),
count=rpois(30, 20)
)
And now we can plot it. But first, let's define the offset to the top bars by finding the maxima height at a year and adding a bit of space
height <- ceiling(max(tapply(dd$count, dd$year, sum))*1.10)
And here's how we plot
ggplot(dd) +
geom_rect(aes(xmin=year-.4, xmax=year+.4,
ymin=ifelse(group=="a", 0, height-count),
ymax=ifelse(group=="a", count, height), fill=group)) +
scale_y_continuous(expand=c(0,0))
And that will give us
I have a dataset where measurements are made for different groups at different days.
I want to have side by side bars representing the measurements at the different days for the different groups with the groups of bars spaced according to day of measurement with errorbars overlaid to them.
I'm having trouble with making the dodging in geom_bar agree with the dodge on geom_errorbar.
Here is a simple piece of code:
days = data.frame(day=c(0,1,8,15));
groups = data.frame(group=c("A","B","C","D", "E"), means=seq(0,1,length=5));
my_data = merge(days, groups);
my_data$mid = exp(my_data$means+rnorm(nrow(my_data), sd=0.25));
my_data$sigma = 0.1;
png(file="bar_and_errors_example.png", height=900, width=1200);
plot(ggplot(my_data, aes(x=day, weight=mid, ymin=mid-sigma, ymax=mid+sigma, fill=group)) +
geom_bar (position=position_dodge(width=0.5)) +
geom_errorbar (position=position_dodge(width=0.5), colour="black") +
geom_point (position=position_dodge(width=0.5), aes(y=mid, colour=group)));
dev.off();
In the plot, the errorsegments appears with a fixed offset from its bar (sorry, no plots allowed for newbies even if ggplot2 is the subject).
When binwidth is adjusted in geom_bar, the offset is not fixed and changes from day to day.
Notice, that geom_errorbar and geom_point dodge in tandem.
How do I get geom_bar to agree with the other two?
Any help appreciated.
The alignment problems are due, in part, to your bars not representing the data you intend. The following lines up correctly:
ggplot(my_data, aes(x=day, weight=mid, ymin=mid-sigma, ymax=mid+sigma, fill=group)) +
geom_bar (position=position_dodge(), aes(y=mid), stat="identity") +
geom_errorbar (position=position_dodge(width=0.9), colour="black") +
geom_point (position=position_dodge(width=0.9), aes(y=mid, colour=group))
This is an old question, but since i ran into the problem today, i want to add the following:
In
geom_bar(position = position_dodge(width=0.9), stat = "identity") +
geom_errorbar( position = position_dodge(width=0.9), colour="black")
the width-argument within position_dodge controls the dodging width of the things to dodge from each other. However, this produces whiskers as wide as the bars, which is possibly undesired.
An additional width-argument outside the position_dodge controls the width of the whiskers (and bars):
geom_bar(position = position_dodge(width=0.9), stat = "identity", width=0.7) +
geom_errorbar( position = position_dodge(width=0.9), colour="black", width=0.3)
The first change I reformatted the code according to the advanced R style guide.
days <- data.frame(day=c(0,1,8,15))
groups <- data.frame(
group=c("A","B","C","D", "E"),
means=seq(0,1,length=5)
)
my_data <- merge(days, groups)
my_data$mid <- exp(my_data$means+rnorm(nrow(my_data), sd=0.25))
my_data$sigma <- 0.1
Now when we look at the data we see that day is a factor and everything else is the same.
str(my_data)
To remove blank space from the plot I converted the day column to factors. CHECK that the levels are in the proper order before proceeding.
my_data$day <- as.factor(my_data$day)
levels(my_data$day)
The next change I made was defining y in your aes arguments. As I'm sure you are aware, this lets ggplot know where to look for y values. Then I changed the position argument to "dodge" and added the stat="identity" argument. The "identity" argument tells ggplot to plot y at x. geom_errorbar inherits the dodge position from geom_bar so you can leave it unspecified, but geom_point does not so you must specify that value. The default dodge is position_dodge(.9).
ggplot(data = my_data,
aes(x=day,
y= mid,
ymin=mid-sigma,
ymax=mid+sigma,
fill=group)) +
geom_bar(position="dodge", stat = "identity") +
geom_errorbar( position = position_dodge(), colour="black") +
geom_point(position=position_dodge(.9), aes(y=mid, colour=group))
sometimes you put aes(x=tasks,y=val,fill=group) in geom_bar rather than ggplot. This causes the problem since ggplot looks forward x and you specify it by the location of each group.
I'm stuck on an small labeling issue with a series of polar histograms made in ggplot2 (circumplexes? how are these things called?).
Here is a simplified example of how the data and the graph look:
df <- data.frame(Attribute1=10, Attribute2=1, Attribute3=2, Attribute4=6, Attribute5=7)
g <- ggplot(melt.data.frame(df), aes(x=variable, y=value, fill=variable, label=value))
g <- g + geom_bar() + geom_text() + coord_polar()
g
Which gives the following graph:
I would like to move the text labels outwards (away from the center).
Normally, I would adjust the position with hjust or vjust inside geom_text(), but it seems that, with coord_polar(), the result is to move all the labels up/downwards or left/rightwards, but not in/outwards.
This may sound trivial - and probably is - but I haven't found any applicable example or workaround yet, so I apologize if this question looks silly.
I'm assuming that you're referring to the numeric values as labels, and that you want them moved a little outside the pie wedges (as opposed to the "Attribute 1" text).
You can just move some of the aesthetic mapping to the geom_text call and add a small value to the y values:
g <- ggplot(melt.data.frame(df), aes(x=variable, y=value, fill=variable))
g <- g + geom_bar() + geom_text(aes(y = value + 0.5,label = value)) + coord_polar()
g