Increase grid.arrange plot size - r

I'm using grid.arrange to display the following three plots on top of each other.
p1 <- ggseasonplot(ng2) + labs(title = "Natural Gas Consumption from Jan. 2001 to Nov. 2021 - Seasonal Plot", x = "Month", y = "Cubic Feet (Millions)") + scale_y_continuous(labels = unit_format(unit = "M", scale = 1e-6))
p2 <- ggsubseriesplot(ng2) + labs(title = "Natural Gas Consumption from Jan. 2001 to Nov. 2021 - Subseries Plot", x = "Month", y = "Cubic Feet (Millions)") + scale_y_continuous(labels = unit_format(unit = "M", scale = 1e-6))
p3 <- ggAcf(ng2, lag.max = 36) + labs(title = "Natural Gas Consumption from Jan. 2001 to Nov. 2021 - ACF Plot", x = "Lag", y = "Correlation")
gridExtra::grid.arrange(p1, p2, p3, nrow = 3, ncol = 1)
The resulting plots are unreadable.
Using the heights function only seems to adjust plot size relative to one another. Any idea how to make each plot larger (longer) as a whole so each is more readable?

In your markdown/knitr chunk, try a value like fig.height = 10
```{r, fig.height = 10}
# Small fig.width
ggplot(cars, aes(speed, dist)) + geom_point()
```
Or you can set the default height for all the figures in an Rmd file
knitr::opts_chunk$set(fig.height = 10)
References
https://community.rstudio.com/t/rmarkdown-rnotebook-text-in-graphs-too-small-lines-to-thin-after-update/123741/3
http://zevross.com/blog/2017/06/19/tips-and-tricks-for-working-with-images-and-figures-in-r-markdown-documents/
Plot size and resolution with R markdown, knitr, pandoc, beamer
https://rmd4sci.njtierney.com/customising-your-figures.html

Related

How to change the legend barheight with scale_fill_gradientn() in R to be able to see the lower-end colors in the legend bar?

I'm trying to create a map with ggplot and fill the countries with scale_fill_gradientn, because I want to manually decide the color pallette. The data includes number of passengers of the Holland America Line per country in a given time period (WOI). To be clear, I want to fill the countries by number of passengers from that country. The problem is that the majority of the data is very low compared to the maximum. So, if you don't adjust the scale values mannualy, you don't see any color difference in the countries with a lower number of passengers.
The dataset of the non-na value countries looks like this:
ID
Region
Number of Passengers
geometry
HR
Croatia
1
list(list(c(16.59681, 16.85476, 16.87604, 16.95796 [...]
LT
Lithuania
3
list(list(c(25.82139, 25.86938, 26.04615, 26.3854, [...]
RO
Romania
5
list(list(c(27.39117, 27.44355, 27.47784, 27.55157 [...]
HU
Hungary
9
list(list(c(22.12108, 22.15531, 22.24829, 22.36416 [...]
DE
Germany
21
list(list(c(8.63593, 9.1131, 9.22352, 9.27178, 9.3 [...]
PL
Poland
73
list(list(c(18.95003, 19.35966, 19.63903, 19.6485, [...]
AT
Austria
122
list(list(c(15.54245, 15.75363, 15.84752, 16.07489 [...]
F
France
158
list(list(c(55.64788, 55.68341, 55.70701, 55.78207 [...]
IT
Italy
592
list(list(c(12.47792, 12.69064, 12.73139, 12.80836 [...]
UK
UK
2941
list(list(c(-0.24042, -0.22283, -0.1984, -0.19125, [...]
NL
Netherlands
35694
list(list(c(6.87491, 6.91836, 6.99302, 7.0784, 7.0 [...]
First I created I shape file to get the geometrics of europe and merged it with the passsengers info.
library(eurostat)
Europe_shp <- get_eurostat_geospatial(resolution = 10,
nuts_level = 0,
year = 2016)
European_Countries_WOI <- merge(country_passengers_europe_code_2_WOI, Europe_shp,
all.x = TRUE, all.y = TRUE,
by.x = "ID", by.y = "id")
I created a map like this and adjusted the scaling.
vector_colors_custom <- c("#6495ED", "#2B386F", "#6317a9", "#9933cc","#A629C2", "#b20000")
map_WOI_1 <- European_Countries_WOI %>%
ggplot(aes(fill = number_of_passengers)) +
aes(geometry = geometry) +
geom_sf(size = 0.1, color = "#F3F3F3") +
scale_fill_gradientn(colours = vector_colors_custom,
values = scales::rescale(c(1, 500, 600, 36000)))+
scale_x_continuous(limits = c(-10, 27)) +
scale_y_continuous(limits = c(33, 70)) +
labs(
title = "Travellers from Europe",
subtitle = "Number of HAL Passengers per Country During Word War I",
caption = "Data: Stadsarchief Rotterdam",
fill = "Number of Passengers"
) +
theme_void() +
theme(
legend.position = c(1.16, 0.5)
)
map_WOI_1
However, the bar is not large enough to show the blue colors. How can I change the barheight? I know it is possible with scale_fill_gradient2_tableau. I want something like below (which I did with scale_fill_gradient2_tableau), but with multiple colors and be able to adjust the colors mannually. Or just be able to rescale the colors in scale_fill_gradient2_tableau, and choose a palette.
The problem is not with the size of the bar, but how you have rescaled the values within scale_fill_gradientn. Perhaps you would be better off with a simple log10 scale, mapping the log of the number of passengers to the fill aesthetic, then specifying the labels appropriately to reconvert the log value back to the original:
European_Countries_WOI %>%
ggplot(aes(fill = log10(number_of_passengers))) +
aes(geometry = geometry) +
geom_sf(size = 0.1, color = "#F3F3F3") +
scale_fill_gradientn(colours = vector_colors_custom,
labels = ~scales::comma(10^.x)) +
scale_x_continuous(limits = c(-10, 27)) +
scale_y_continuous(limits = c(33, 70)) +
labs(
title = "Travellers from Europe",
subtitle = "Number of HAL Passengers per Country During Word War I",
caption = "Data: Stadsarchief Rotterdam",
fill = "Number of Passengers"
) +
theme_void() +
theme(plot.margin = margin(20, 0, 20, 20))
You can increase the bar size too if you want, but this will not affect its limits:
European_Countries_WOI %>%
ggplot(aes(fill = log10(number_of_passengers))) +
aes(geometry = geometry) +
geom_sf(size = 0.1, color = "#F3F3F3") +
scale_fill_gradientn(colours = vector_colors_custom,
labels = ~scales::comma(10^.x)) +
scale_x_continuous(limits = c(-10, 27)) +
scale_y_continuous(limits = c(33, 70)) +
labs(
title = "Travellers from Europe",
subtitle = "Number of HAL Passengers per Country During Word War I",
caption = "Data: Stadsarchief Rotterdam",
fill = "Number of Passengers"
) +
theme_void() +
theme(plot.margin = margin(20, 0, 20, 20),
legend.key.height = unit(0.15, 'npc'))

Problem with colouring a GG Plot Histogram

I`ve got an issue with colouring a ggplot2 histogram.
R-Junk
ggplot(Hospital, aes(x=BodyTemperature)) +
geom_histogram(aes(fill = factor(BodyTemperature))) +
scale_x_continuous(breaks = seq(0, 100, by = 10)) +
ylab("prevalence") +
xlab("BodyTemperature") +
ggtitle("Temperature vs. prevalence")
So the histogram should plot the information (x-axis), that as higher the temperature gets, the worse it is. So for example „temperature“ at 36°C should be green, 38°C yellow, 40° red - going from left to right on the x-axis.
Y-Axis should provide how often these temperatures ocures in the Patientdata of the Hospital. The Data "BodyTemperature" is a list of 200+ Data like: "35.3" or "37.4" etc.
How can this chunk be fixed to provide the color changes? For a non-ggplot version ive already written this r-junk positiv:
```{r, fig.width=8}
color1 <- rep(brewer.pal(1, "Greens"))
color2 <- rep("#57c4fa", 0)
color3 <- brewer.pal(8, "Reds")
hist(Hospital$BodyTemperature[-357],
breaks = seq(from = 0, to = 100, by = 10),
main = "Temperature vs. prevalence",
ylab = "prevalence",
xlab = "Temperature",
col = c(color1, color2, color3))
```
The key is to make sure the bin intervals used for the fill scale match those used for the x axis. You can do this by setting the binwidth argument to geom_histogram(), and using ggplot2::cut_width() to break BodyTemperature into the same bins for the fill scale:
set.seed(13)
library(ggplot2)
# example data
Hospital <- data.frame(BodyTemperature = 36.5 + rchisq(100, 2))
ggplot(Hospital, aes(BodyTemperature)) +
geom_histogram(
aes(fill = cut_width(BodyTemperature, width = 1)),
binwidth = 1,
show.legend = FALSE
) +
scale_fill_brewer(palette = "RdYlGn", direction = -1) +
labs(
title = "Temperature vs. Prevalence",
x = "Body Temperature (°C)",
y = "Prevalence"
) +
theme_minimal()
Created on 2022-10-24 with reprex v2.0.2

Incomplete display of plot due to ylim

I have a question about the restricted representation of a plot. The limits of the y axis should range from 0-5. Due to ceiling and ground effects the plot is now partly not displayed correctly. See attachment. How can I get the plots to be displayed completely without having to change the scaling? Thank you, you are very helpful!
# visual inspection of data
fit<-Anxiety_full
# Plot model
plot_Anxiety <- plot_model(fit, type = "eff", terms = c("Condition", "Group"))+ #geom_line(size = 1)
coord_cartesian(xlim = c(0.5, NA), clip = "off") + theme_tq() +scale_colour_tq() + scale_fill_tq(light) +
labs(
title = "",
y = "Anxiety Score [ 0-5 ]",
x = "") + xlim(c("baseline", "60 bpm", "16 bpm", "10 bpm", "6 bpm", "random")) +
ylim(c(-0.5,5.5)
)+ ggplot2::labs(colour = "Group") + scale_color_manual(values=c('Red','Black'))
plot_Anxiety<- plot_Anxiety + theme_apa()
plot_Anxiety

Colour segments of density plot by bin

Warning, I am brand-new to R!
I have the R bug and having a play with the possibilities but getting very lost. I want to try and colour segments of a density plot with a condition '>' to indicate bins. In my head it look like:
...but not quartile or % change dependant.
My data shows; x = duration (number of days) and y = frequency. I would like the plot to colour split on 3 month intervals up to 12 months and one colour after (using working days i.e. 63 = 3 months).
I have had a go, but really not sure where to start!
ggplot(df3, aes(x=Investigation.Duration))+
geom_density(fill = W.S_CleanNA$Investigation.Duration[W.S_CleanNA$Investigation.Duration>0],
fill = W.S_CleanNA$Investigation.Duration[W.S_CleanNA$Investigation.Duration>63], color = "white",
fill = W.S_CleanNA$Investigation.Duration[W.S_CleanNA$Investigation.Duration>127], color = "light Grey",
fill = W.S_CleanNA$Investigation.Duration[W.S_CleanNA$Investigation.Duration>190], color = "medium grey",
fill = W.S_CleanNA$Investigation.Duration[W.S_CleanNA$Investigation.Duration>253], color = "dark grey",
fill = W.S_CleanNA$Investigation.Duration[W.S_CleanNA$Investigation.Duration>506], color = "black")+
ggtitle ("Investigation duration distribution in 'Wales' complexity sample")+
geom_text(aes(x=175, label=paste0("Mean, 136"), y=0.0053))+
geom_vline(xintercept = c(136.5), color = "red")+
geom_text(aes(x=80, label=paste0("Median, 129"), y=0.0053))+
geom_vline(xintercept = c(129.5), color = "blue")
Any really simple help much appreciated.
Unfortunately, you can't do this directly with geom_density, as "under the hood" it is built with a single polygon, and a polygon can only have a single fill. The only way to do this is to have multiple polygons, and you need to build them yourself.
Fortunately, this is easier than it sounds.
There was no sample data in the question, so we will create a plausible distribution with the same median and mean:
#> Simulate data
set.seed(69)
df3 <- data.frame(Investigation.Duration = rgamma(1000, 5, 1/27.7))
round(median(df3$Investigation.Duration))
#> [1] 129
round(mean(df3$Investigation.Duration))
#> [1] 136
# Get the density as a data frame
dens <- density(df3$Investigation.Duration)
dens <- data.frame(x = dens$x, y = dens$y)
# Exclude the artefactual times below zero
dens <- dens[dens$x > 0, ]
# Split into bands of 3 months and group > 12 months together
dens$band <- dens$x %/% 63
dens$band[dens$band > 3] <- 4
# This us the complex bit. For each band we want to add a point on
# the x axis at the upper and lower ltime imits:
dens <- do.call("rbind", lapply(split(dens, dens$band), function(df) {
df <- rbind(df[1,], df, df[nrow(df),])
df$y[c(1, nrow(df))] <- 0
df
}))
Now we have the polygons, it's just a case of drawing and labelling appropriately:
library(ggplot2)
ggplot(dens, aes(x, y)) +
geom_polygon(aes(fill = factor(band), color = factor(band))) +
theme_minimal() +
scale_fill_manual(values = c("#003f5c", "#58508d", "#bc5090",
"#ff6361", "#ffa600"),
name = "Time",
labels = c("Less than 3 months",
"3 to 6 months",
"6 to 9 months",
"9 to 12 months",
"Over 12 months")) +
scale_colour_manual(values = c("#003f5c", "#58508d", "#bc5090",
"#ff6361", "#ffa600"),
guide = guide_none()) +
labs(x = "Days since investigation started", y = "Density") +
ggtitle ("Investigation duration distribution in 'Wales' complexity sample") +
geom_text(aes(x = 175, label = paste0("Mean, 136"), y = 0.0053),
check_overlap = TRUE)+
geom_vline(xintercept = c(136.5), linetype = 2)+
geom_text(aes(x = 80, label = paste0("Median, 129"), y = 0.0053),
check_overlap = TRUE)+
geom_vline(xintercept = c(129.5), linetype = 2)

Plotting baseball pitches as qualitative variable by color

I was thinking of doing this in R but am new to it and would appreciate any help
I have a dataset (pitches) of baseball pitches identified by
'pitchNumber' and 'outcome' e.g S = swinging strike, B = ball, H= hit
etc.
e.g.
1 B ;
2 H ;
3 S ;
4 S ;
5 X ;
6 H; etc.
All I want to do is have a graph that plots them in a line cf BHSSXB
but replacing the letter with a small bar colored to represent the letter, with a legend, and optionally having the pitch number above the color . Somewhat like a sparkline.
Any suggestion on how to implement this much appreciated
And the same graph using ggplot.
Data courtesy of #GavinSimpson.
ggplot(baseball, aes(x=pitchNumber, y=1, ymin=0, ymax=1, colour=outcome)) +
geom_point() +
geom_linerange() +
ylab(NULL) +
xlab(NULL) +
scale_y_continuous(breaks=c(0, 1)) +
opts(
panel.background=theme_blank(),
panel.grid.minor=theme_blank(),
axis.text.y = theme_blank()
)
Here is a base graphics idea from which to work. First some dummy data:
set.seed(1)
baseball <- data.frame(pitchNumber = seq_len(50),
outcome = factor(sample(c("B","H","S","S","X","H"),
50, replace = TRUE)))
> head(baseball)
pitchNumber outcome
1 1 H
2 2 S
3 3 S
4 4 H
5 5 H
6 6 H
Next we define the colours we want:
## better colours - like ggplot for the cool kids
##cols <- c("red","green","blue","yellow")
cols <- head(hcl(seq(from = 0, to = 360,
length.out = nlevels(with(baseball, outcome)) + 1),
l = 65, c = 100), -1)
then plot the pitchNumber as a height 1 histogram-like bar (type = "h"), suppressing the normal axes, and we add on points to the tops of the bars to help visualisation:
with(baseball, plot(pitchNumber, y = rep(1, length(pitchNumber)), type = "h",
ylim = c(0, 1.2), col = cols[outcome],
ylab = "", xlab = "Pitch", axes = FALSE, lwd = 2))
with(baseball, points(pitchNumber, y = rep(1, length(pitchNumber)), pch = 16,
col = cols[outcome]))
Add on the x-axis and the plot frame, plus a legend:
axis(side = 1)
box()
## note: this assumes that the levels are in alphabetical order B,H,S,X...
legend("topleft", legend = c("Ball","Hit","Swinging Strike","X??"), lty = 1,
pch = 16, col = cols, bty = "n", ncol = 2, lwd = 2)
Gives this:
This is in response to your last comment on #Gavin's answer. I'm going to build off of the data provided by #Gavin and the ggplot2 plot by #Andrie. ggplot() supports the concept of faceting by a variable or variables. Here you want to facet by pitcher and at the pitch limit of 50 per row. We'll create a new variable that corresponds to each row we want to plot separately. The equivalent code in base graphics would entail adjusting mfrow or mfcol in par() and calling separate plots for each group of data.
#150 pitches represents a somewhat typical 9 inning game.
#Thanks to Gavin for sample data.
longGame <- rbind(baseball, baseball, baseball)
#Starter goes 95 pitches, middle relief throws 35, closer comes in for 20 and the glory
longGame$pitcher <- c(rep("S", 95), rep("M", 35), rep("C",20))
#Adjust pitchNumber accordingly
longGame$pitchNumber <- c(1:95, 1:35, 1:20)
#We want to show 50 pitches at a time, so will combine the pitcher name
#with which set of pitches this is
longGame$facet <- with(longGame, paste(pitcher, ceiling(pitchNumber / 50), sep = ""))
#Create the x-axis in increments of 1-50, by pitcher
longGame <- ddply(longGame, "facet", transform, pitchFacet = rep(1:50, 5)[1:length(facet)])
#Convert facet to factor in the right order
longGame$facet <- factor(longGame$facet, levels = c("S1", "S2", "M1", "C1"))
#Thanks to Andrie for ggplot2 function. I change the x-axis and add a facet_wrap
ggplot(longGame, aes(x=pitchFacet, y=1, ymin=0, ymax=1, colour=outcome)) +
geom_point() +
geom_linerange() +
facet_wrap(~facet, ncol = 1) +
ylab(NULL) +
xlab(NULL) +
scale_y_continuous(breaks=c(0, 1)) +
opts(
panel.background=theme_blank(),
panel.grid.minor=theme_blank(),
axis.text.y = theme_blank()
)
You can obviously change the labels for the facet variable, but the above code will produce:

Resources