I have a simple dataset:
myData<-structure(list(Name = c("Rick", "Rick", "Rick", "Rick", "Rick",
"Rick", "Rick", "Rick", "Jane", "Jane", "Jane", "Jane", "Jane",
"Jane", "Jane", "Jane", "Ellen", "Ellen", "Ellen", "Ellen", "Ellen",
"Ellen", "Ellen", "Ellen"), City = c("Boston", "Boston", "Boston",
"Boston", "Seattle", "Seattle", "Seattle", "Seattle", "Boston",
"Boston", "Boston", "Boston", "Seattle", "Seattle", "Seattle",
"Seattle", "Boston", "Boston", "Boston", "Boston", "Seattle",
"Seattle", "Seattle", "Seattle"), Transport = c("Car", "Train",
"Bus ", "Plane", "Car", "Train", "Bus ", "Plane", "Car", "Train",
"Bus ", "Plane", "Car", "Train", "Bus ", "Plane", "Car", "Train",
"Bus ", "Plane", "Car", "Train", "Bus ", "Plane"), Time = c(0L,
1L, 0L, 9L, 0L, 0L, 3L, 7L, 1L, 3L, 2L, 0L, 0L, 2L, 3L, 0L, 1L,
3L, 3L, 4L, 8L, 4L, 7L, 7L)), class = "data.frame", row.names = c(NA,
-24L))
I want a ggplot that looks in this way: City on the X axis, Time on Y axis, and the value of each column filled with the different transport. But I would like to have the data on the X axis also grouped by person. So far I've wrote:
city<-as.factor(myData$City)
Transport<-myData$Transport
time<-myData$Time
p<-ggplot(myData,
aes(x=city,
y=time,
fill=Transport))
geom_bar(position="dodge",
stat="identity")
scale_color_viridis(discrete = TRUE)
scale_fill_viridis(discrete = TRUE)
scale_x_discrete(breaks = waiver(),
limits=NULL)
scale_y_continuous(limits = c(0, 10),
breaks = seq(0, 10, by = 1))
xlab("City")
ylab("Time")
ggtitle("People")
theme(axis.line = element_blank(),
axis.text.x=element_text(size=14,
margin=margin(b=10),
colour="black"),
axis.text.y=element_text(size=14,
margin=margin(l=10),
colour="black"),
axis.ticks = element_blank(),
axis.title=element_text(size=18,
face="bold"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank(),
plot.title = element_text(size=18,
hjust=0.5),
legend.text = element_text(size=14),
legend.title = element_text(size=18))
p
I cannot figure out how to group data on the X axis based on the person's name. I tried to use group=name
(both using name<-myData$name
and name<-as.factor(myData$Name)
) inside and outside aes()
but it is not working.
I don't know if this plot has sense or if there is a better way to visualize this, but I wanted to try.
CodePudding user response:
It sounds as though you are looking for a nested categorical x axis. You do can do this using the 'facet that doesn't look like a facet' trick, which works particularly well with the styling you have chosen.
A few other points to consider:
- You don't need to make a copy of the vectors you want to use out of your data frame. You can use the names of the columns in your data frame directly in ggplot
geom_bar(stat = "identity")
is just a long way of writinggeom_col()
- You haven't mapped the color aesthetic, so
scale_color_viridis
doesn't do anything - You can save some time and space by using
labs
, and setting your x, y, and title labels there in a single call. - Your
scale_x_discrete
wasn't changing anything in the plot and can be removed. - Instead of setting every single
theme
parameter, start with a theme that is close to the one you want, then only changing what you need to. Remember, the more things you have to explicitly code, the harder your script gets to read and debug.
Putting all these together, we have:
ggplot(myData, aes(Name, Time, fill = Transport))
geom_col(position = "dodge")
scale_fill_viridis_d()
scale_y_continuous(limits = c(0, 10), breaks = 0:10)
labs(x = "City", y = "Time", title = "People")
facet_grid(. ~ City, switch = 'x')
theme_minimal(base_size = 14)
theme(strip.placement = 'outside',
strip.background = element_blank(),
strip.text = element_text(size = 15, face = 'bold'),
axis.ticks = element_blank(),
axis.title = element_text(size = 18, face = "bold"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
plot.title = element_text(size = 18, hjust = 0.5, face = 'bold'))