R ggplot2 (mpg): Group boxplot by year rather than drv - r

I am working my way through R4DS, and am trying to tweak my solution for 3.8.1 exercise 4. I ended up with the following code:
ggplot(data = mpg, mapping = aes(x = manufacturer, y = hwy/cty, colour = year)) +
geom_boxplot() + coord_flip()
This does not work as intended. But when I replace colour = year with colour = drv, I get a nice grouped boxplot. Why can’t this be done with year?
RStudio 0.99.902; ggplot2 v. 2.1.0.

Seems to work when you write it into geom_boxplot.
ggplot(data = mpg, mapping = aes(x = manufacturer, y = hwy/cty)) +
geom_boxplot(aes(colour=factor(year))) + coord_flip()

Related

create single ggplot figure with a standalone ggplot and a ggplot created with facet_wrap()?

I have my an empty panel in my facetted ggplot. I would like to insert my standalone plot into this. Is this possible? See below for example code.
I found a possible solution Here, but can't get it to 'look nice'. To 'look nice' I want the standalone plot to have the same dimensions as one of the facetted plots.
library(ggplot2)
library(plotly)
data("mpg")
first_plot = ggplot(data = mpg, aes(x = trans, y = cty)) +
geom_point(size= 1.3)
facet_plot = ggplot(data = mpg, aes(x = year, y = cty)) +
geom_point(size = 1.3) +
facet_wrap(~manufacturer)
facet_plot # room for one more panel which I want first_plot to go?
# try an merge but makes first plot huge, compared with facetted plots.
subplot(first_plot, facet_plot, which_layout = 2)
Besides the options to manipulate the gtable or using patchwork one approach to achieve your desired result would be via some data wrangling to add the standalone plot as an additional facet. Not sure whether this will work for your real data but at least for mpg you could do:
library(ggplot2)
library(dplyr)
mpg_bind <- list(standalone = mpg, facet = mpg) %>%
bind_rows(.id = "id") %>%
mutate(x = ifelse(id == "standalone", trans, year),
facet = ifelse(id == "standalone", "all", manufacturer),
facet = forcats::fct_relevel(facet, "all", after = 1000))
ggplot(data = mpg_bind, aes(x = x, y = cty)) +
geom_point(size = 1.3) +
facet_wrap(~facet, scales = "free_x")

Unintended line across X axis of density plot (r)

I am trying to identify why I have a purple line appearing along the x axis that is the same color as "Prypchan, Lida" from my legend. I took a look at the data and do not see any issues there.
ggplot(LosDoc_Ex, aes(x = LOS)) +
geom_density(aes(colour = AttMD)) +
theme(legend.position = "bottom") +
xlab("Length of Stay") +
ylab("Distribution") +
labs(title = "LOS Analysis * ",
caption = "*exluding Residential and WSH",
color = "Attending MD: ")
Usually I'd wait for a reproducible example, but in this case, I'd say the underlying explanation is really quite straightforward:
geom_density() creates a polygon, not a line.
Using a sample dataset from ggplot2's own package, we can observe the same straight line below the density plots, covering the x-axis & y-axis. The colour of the line simply depends on which plot is on top of the rest:
p <- ggplot(diamonds, aes(carat, colour = cut)) +
geom_density()
Workaround 1: You can manually calculate the density values yourself for each colour group in a new data frame, & plot the results using geom_line() instead of geom_density():
library(dplyr)
library(tidyr)
library(purrr)
diamonds2 <- diamonds %>%
nest(-cut) %>%
mutate(density = map(data, ~density(.x$carat))) %>%
mutate(density.x = map(density, ~.x[["x"]]),
density.y = map(density, ~.x[["y"]])) %>%
select(cut, density.x, density.y) %>%
unnest()
ggplot(diamonds2, aes(x = density.x, y = density.y, colour = cut)) +
geom_line()
Workaround 2: Or you can take the data generated by the original plot, & plot that using geom_line(). The colours would need to be remapped to the legend values though:
lp <- layer_data(p)
if(is.factor(diamonds$cut)) {
col.lev = levels(diamonds$cut)
} else {
col.lev = sort(unique(diamonds$cut))
}
lp$cut <- factor(lp$group, labels = col.lev)
ggplot(lp, aes(x = x, y = ymax, colour = cut)) +
geom_line()
There are two simple workarounds. First, if you only want lines and no filled areas, you can simply use geom_line() with the density stat:
library(ggplot2)
ggplot(diamonds, aes(x = carat, y = stat(density), colour = cut)) +
geom_line(stat = "density")
Note that for this to work, we need to set the y aesthetic to stat(density).
Second, if you want the area under the lines to be filled, you can use geom_density_line() from the ggridges package. It works exactly like geom_density() but draws a line (with filled area underneath) rather than a polygon.
library(ggridges)
ggplot(diamonds, aes(x = carat, colour = cut, fill = cut)) +
geom_density_line(alpha = 0.2)
Created on 2018-12-14 by the reprex package (v0.2.1)

Only display label per category

I have the following dataset:
year <- as.factor(c(1999,2000,2001))
era <- c(0.4,0.6,0.7)
player_id <- as.factor(c(2,2,2))
df <- data.frame(year, era, player_id)
Using this data I created the following graph:
ggplot(data = df, aes(x = year, y=era, colour = player_id))+
geom_line() +
geom_text(aes(label = player_id), hjust=0.7)
Thing is however that I do now get a label at every datapoint. I only want to have a label at the end of each datapoint.
Any thoughts on what I should change to I get only one label?
If I understand correctly, you want label at end of data point. You could do this using directlabels library, as below:
library(ggplot2)
library(directlabels)
ggplot(data = df, aes(x = year, y=era, group = player_id, colour = player_id))+
geom_line() +
scale_colour_discrete(guide = 'none') +
scale_x_discrete(expand=c(0, 1)) +
geom_dl(aes(label = player_id), method = list(dl.combine("last.points"), cex = 0.8))
Output:
If I am understanding correctly what you want, then you can replace the geom_text(...) with geom_point()

Plot proportion in bar chart grouped by another variable

I am currently reading R for Data Science and trying to create some graphs. I understand that to get proportion in bar chart, you need to use group = 1. For example, the code below works:
library(ggplot2)
ggplot(data = diamonds) + geom_bar(mapping = aes(x = cut, fill = color))
But I don't get the same plot for proportions.
ggplot(data = diamonds) + geom_bar(mapping = aes(x = cut, fill = color, y = ..prop.., group = 1))
I do get proportion but not by color.
Here's one way to do it using ..count..
require(ggplot2)
ggplot(diamonds,aes(cut,..count../sum(..count..),fill=color))+
geom_bar()+
scale_y_continuous(labels=scales::percent)

How to create a heatmap with continuous scale using ggplot2 in R

I have got a data frame with several 1000 rows in the form of
group = c("gr1","gr1","gr1","gr1","gr1","gr1","gr1","gr1","gr1","gr1","gr2","gr2","gr2","gr2","gr2","gr2","gr2","gr2","gr2","gr2","gr3","gr3","gr3","gr3","gr3","gr3","gr3","gr3","gr3","gr3")
pos = c(1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10)
color = c(2,2,2,2,3,3,2,2,3,2,1,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,1,1,2,2)
df = data.frame(group, pos, color)
and would like to make a kind of heatmap in which one axes has a continuous scale (position). The color column is categorical. However due to the large amount of data points I want to use binning, i.e. use it as a continuous variable.
This is more or less how the plot should look like:
I can't think of a way to create such a plot using ggplot2/R. I have tried several geometries, e.g. geom_point()
ggplot(data=df, aes(x=strain, y=pos, color=color)) +
geom_point() +
scale_colour_gradientn(colors=c("yellow", "black", "orange"))
Thanks for your help in advance.
Does this help you?
library(ggplot2)
group = c("gr1","gr1","gr1","gr1","gr1","gr1","gr1","gr1","gr1","gr1","gr2","gr2","gr2","gr2","gr2","gr2","gr2","gr2","gr2","gr2","gr3","gr3","gr3","gr3","gr3","gr3","gr3","gr3","gr3","gr3")
pos = c(1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10)
color = c(2,2,2,2,3,3,2,2,3,2,1,2,2,2,1,1,1,1,1,1,2,2,2,2,2,2,1,1,2,2)
df = data.frame(group, pos, color)
ggplot(data = df, aes(x = group, y = pos)) + geom_tile(aes(fill = color))
Looks like this
Improved version with 3 color gradient if you like
library(scales)
ggplot(data = df, aes(x = group, y = pos)) + geom_tile(aes(fill = color))+ scale_fill_gradientn(colours=c("orange","black","yellow"),values=rescale(c(1, 2, 3)),guide="colorbar")

Resources