facet_grid different panel sizes - r

I try to make panel hights in facet_grid() to fit the plot - not be equal for every panel.
I found this: Different y-Axis Labels facet_grid and sizes
Sadly it doesn't work :(
Here is my code, I'm using now
dane <- tibble(
"obszar" = c("Ludzie", "Ludzie", "Ludzie", "Ludzie",
"Myślenie", "Myślenie", "Myślenie",
"Zarządzanie", "Zarządzanie"),
"kompetencja" = c("Współdziałanie", "Komunikowanie i przekonywanie",
"Współdziałanie2", "Komunikowanie i przekonywanie2",
"Planowanie", "Wnioskowanie", "Innowacyjność",
"Budowanie zaangażowanego zespołu", "Inspirowanie i motywowanie"),
"wynik" = c(3,3,4,2,3,6,5,4,2),
"profil" = c(4,4,4,5,4,4,4,5,5)) %>%
mutate(luka = wynik - profil) %>%
arrange(obszar, kompetencja)
ggplot(dane, aes(x=kompetencja, y=wynik)) +
geom_segment(aes(x=kompetencja ,xend=kompetencja, y=1, yend=profil), color=kolor2) +
geom_point(aes(y = profil), pch = 19, size=3, color= kolor2) +
theme_bw() +
coord_flip(ylim=c(1,7)) +
theme(
legend.position = "none",
axis.text.x = element_text(size = 12),
axis.text.y = element_text(hjust = 1, size = 12),
panel.border = element_blank(),
axis.ticks=element_blank(),
axis.line.y = element_line(colour = "grey50"),
panel.grid.major.x = element_line(colour = "grey80", size = 0.2),
panel.grid.minor.x = element_blank(),
panel.grid.major.y = element_blank(),
panel.grid.minor.y = element_blank()
) +
scale_y_continuous(breaks=seq(1,7,1)) +
labs(title = NULL,
caption = "źródło: opracowanie własne",
x = NULL,
y = NULL) +
annotate("rect", xmin = -Inf, ymin = 1, xmax = Inf, ymax = 2.5, fill = kolor2, alpha = 0.2) +
annotate("rect", xmin = -Inf, ymin = 5.5, xmax = Inf, ymax = 7.0, fill = kolor2, alpha = 0.2) +
facet_grid(obszar ~ ., scales = "free")
Output gives me 3 panels of hight equal to the highest one. I would like to get panels with heights adequate to the number of segments in the plot.
result of my code

Related

the rectangles color in ggplot using geom_rec

I want to have two rectangles
1- xmin=0.3,xmax=.7, ymin=5, ymax=100 with a bit dark gray
2- xmin=0.3,xmax=.7, ymin=3, ymax=5 with light gray
I used the following but I could not get what I need.
p[[1]] <-ggplot(mat_ind, aes(x = times1, y = mat_ind[,1])) +
geom_line() +ylab("") +
xlab("") + ylim(-6,100)+xlim(0.3,.7)+ theme(panel.grid = element_blank(),
axis.title = element_blank(),
axis.text.x = element_blank(),
plot.margin=unit(c(1,-1,0,0),"cm"))+theme_bw()+
geom_rect(data=mat_ind, inherit.aes=FALSE,
aes(xmin=0.3,xmax=.7, ymin=5, ymax=100, fill="gray45"), alpha=0.01 )+
geom_rect(data=mat_ind, inherit.aes=FALSE,
aes(xmin=0.3,xmax=.7, ymin=3, ymax=5, fill= "grey"), alpha=0.01 )
Could you please lead me to do that.
We don't have your data, but let's create some with the same names:
times1 <- seq(0.3, 0.7, length.out = 100)
mat_ind <- as.data.frame(matrix(cumsum(runif(100)), ncol = 1))
If you want to add specific rectangles as annotations, you should use annotate rather than geom_rect. Otherwise, you are likely to get multiple copies of the rectangles:
library(ggplot2)
ggplot(data = mat_ind, aes(x = times1, y = mat_ind[,1])) +
geom_line() +
annotate("rect", xmin = 0.3, xmax = .7, ymin = 5, ymax = 100,
fill = "gray45", alpha = 0.5) +
annotate("rect", xmin = 0.3, xmax = .7, ymin = 3, ymax = 5, fill= "grey",
alpha = 0.5) +
xlab("") +
ylab("") +
ylim(-6,100) +
xlim(0.3,.75) +
theme_bw() +
theme(panel.grid = element_blank(),
axis.title = element_blank(),
axis.text.x = element_blank(),
plot.margin = unit(c(1, -1, 0, 0), "cm"))
Created on 2020-12-07 by the reprex package (v0.3.0)

How to put axis element inside a box using ggplot

I searched about my problem but apparently, there is no topic about this. Any help will be appreciated.
Suppose I have a plot generated by:
library(tidyverse)
df<- data.frame(PCP = c("BOB","FRED","ED","Other"),
closed = c(42,64,45,1812),
total= c(53,81,58,3188),
percentage = c(.7924,.7901,.7758,.5683),
row= c(1, 2, 3,4),
color =c("0099FF","#CCCCCC","#CCCCCC","#660033"),
color_fill = c("99","0","0","98"
))
col <- c(
"99" = "#0099FF",
"98" = "#660033",
"0" = "#CCCCCC"
)
df %>%
arrange(desc(percentage)) %>%
mutate(PCP = PCP,
closed = closed,
total = total,
percentage = percentage,
row = row,
color = color,
color_fill = color_fill) -> df1
ggplot(df1,aes(x=PCP, y = percentage,fill=color_fill, color = color)) +
geom_col() +
coord_flip() +
labs(x ="PCP Name",
y = "Percentage of Gap Closures",
title = "TOP 10 PCPs")+
scale_fill_manual(values = col)+
scale_color_manual(values = col) +
theme(legend.position = "none",
panel.grid = element_blank(),
panel.background = element_blank(),
text = element_text(size=15),
plot.caption = element_text(hjust = 0, face= "italic"),
axis.text.y = element_text(colour = col ))
How can I put 0.6 on the x-axis and FRED on the y-axis inside a colored box?
have a look here by using two annotate (note coord_filp() is updated)
ggplot(df1,aes(x=PCP, y = percentage,fill=color_fill, color = color)) +
geom_col() +
#coord_flip() +
labs(x ="PCP Name",
y = "Percentage of Gap Closures",
title = "TOP 10 PCPs")+
scale_fill_manual(values = col)+
scale_color_manual(values = col) +
theme(legend.position = "none",
panel.grid = element_blank(),
panel.background = element_blank(),
text = element_text(size=15),
plot.caption = element_text(hjust = 0, face= "italic"),
axis.text.y = element_text(colour = col )) +
annotate("rect", xmin = 2.8, xmax = 3.2, ymin = -0.091, ymax = -0.045, alpha=0.5, fill="red") +
annotate("rect", xmin = 0.2, xmax = 0.35, ymin = 0.58, ymax = 0.62, alpha=0.5, fill="red") +
coord_flip(xlim = c(1,4), ylim = c(0, 0.8), clip = "off")
If you insist on a "box", then perhaps use segment instead of rect for the annotate.

Creating a linear gauge in R with ggplot2: reducing barplot width

I have created a linear gauge in R to be displayed within PowerBI.
My only issue is that the width of the plot cannot be adjusted so I am getting the following:
(Plot is being rendered in PowerBI)
Whereas I would like to obtain the same graph but half the width.
I tried using width within geom_bar but it resizes the bar and the final output is the same.
Ideally, the bar would be half its current width (I am building this graph for a PowerBI report).
This is the code I used:
library(ggplot2)
scores = factor(c('Inadequate','Adequate','Fair','Good','Great','Excellent','Exceptional'),
levels = (c('Inadequate','Adequate','Fair','Good','Great','Excellent','Exceptional')),
ordered = TRUE)
x <- data.frame(points = rep(1,7), scores= scores)
x %>%
ggplot(aes(x=points, fill=scores)) +
geom_bar(position = "stack", show.legend = FALSE) +
geom_text(aes(label=scores, y = seq(from=0.5, to=6.5, by = 1)), label.size = 0.25)+
coord_flip() +
theme(panel.background = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.line = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank(),
axis.text = element_blank()) +
geom_point(aes(x= 1.45, y=5), shape = 25, size=10, colour = "black", fill = "black") +
geom_point(aes(x= 0.55, y=3), shape = 24, size=10, colour = "black", fill = "black") +
geom_point(aes(x= 0.55, y=6), shape = 24, size=10, colour = "black", fill = "black") +
scale_fill_brewer(palette = "RdYlGn", direction = -1)
If simply resizing the Power BI visual is no option, you can use theme(plot.margin = unit(c(0, 0.2, 0, 0.2), "npc")) for increasing margins that ggplot draws around plot. Full code:
library(tidyverse)
scores = factor(c('Inadequate','Adequate','Fair','Good','Great','Excellent','Exceptional'),
levels = (c('Inadequate','Adequate','Fair','Good','Great','Excellent','Exceptional')),
ordered = TRUE)
x <- data.frame(points = rep(1,7), scores= scores)
x %>%
ggplot(aes(x=points, fill=scores)) +
geom_bar(position = "stack", show.legend = FALSE) +
geom_text(aes(label=scores, y = seq(from=0.5, to=6.5, by = 1)), label.size = 0.25)+
coord_flip() +
theme(panel.background = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.line = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank(),
axis.text = element_blank()) +
geom_point(aes(x= 1.45, y=5), shape = 25, size=10, colour = "black", fill = "black") +
geom_point(aes(x= 0.55, y=3), shape = 24, size=10, colour = "black", fill = "black") +
geom_point(aes(x= 0.55, y=6), shape = 24, size=10, colour = "black", fill = "black") +
scale_fill_brewer(palette = "RdYlGn", direction = -1) +
theme(plot.margin = unit(c(0, 0.2, 0, 0.2), "npc"))

ggplot2 barplot with dual Y-axis and error bars

I am trying to generate a barplot with dual Y-axis and error bars. I have successfully generated a plot with error bars for one variable but I don't know how to add error bars for another one. My code looks like this. Thanks.
library(ggplot2)
#Data generation
Year <- c(2014, 2015, 2016)
Response <- c(1000, 1100, 1200)
Rate <- c(0.75, 0.42, 0.80)
sd1<- c(75, 100, 180)
sd2<- c(75, 100, 180)
df <- data.frame(Year, Response, Rate,sd1,sd2)
df
# The errorbars overlapped, so use position_dodge to move them horizontally
pd <- position_dodge(0.7) # move them .05 to the left and right
png("test.png", units="in", family="Times", width=2, height=2.5, res=300) #pointsize is font size| increase image size to see the key
ggplot(df) +
geom_bar(aes(x=Year, y=Response),stat="identity", fill="tan1", colour="black")+
geom_errorbar(aes(x=Year, y=Response, ymin=Response-sd1, ymax=Response+sd1),
width=.2, # Width of the error bars
position=pd)+
geom_line(aes(x=Year, y=Rate*max(df$Response)),stat="identity",color = 'red', size = 2)+
geom_point(aes(x=Year, y=Rate*max(df$Response)),stat="identity",color = 'black',size = 3)+
scale_y_continuous(name = "Left Y axis", expand=c(0,0),limits = c(0, 1500),breaks = seq(0, 1500, by=500),sec.axis = sec_axis(~./max(df$Response),name = "Right Y axis"))+
theme(
axis.title.y = element_text(color = "black"),
axis.title.y.right = element_text(color = "blue"))+
theme(
axis.text=element_text(size=6, color = "black",family="Times"),
axis.title=element_text(size=7,face="bold", color = "black"),
plot.title = element_text(color="black", size=5, face="bold.italic",hjust = 0.5,margin=margin(b = 5, unit = "pt")))+
theme(axis.text.x = element_text(angle = 360, hjust = 0.5, vjust = 1.2,color = "black" ))+
theme(axis.line = element_line(size = 0.2, color = "black"),axis.ticks = element_line(colour = "black", size = 0.2))+
theme(axis.ticks.length = unit(0.04, "cm"))+
theme(plot.margin=unit(c(1,0.1,0.1,0.4),"mm"))+
theme(axis.title.y = element_text(margin = margin(t = 0, r = 4, b = 0, l = 0)))+
theme(axis.title.x = element_text(margin = margin(t = 0, r = 4, b = 2, l = 0)))+
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_blank())+
ggtitle("SRG3")+
theme(legend.position="top")+
theme( legend.text=element_text(size=4),
#legend.justification=c(2.5,1),
legend.key = element_rect(size = 1.5),
legend.key.size = unit(0.3, 'lines'),
legend.position=c(0.79, .8), #width and height
legend.direction = "horizontal",
legend.title=element_blank())
dev.off()
and my plot is as follows:
A suggestion for future questions: your example is far from being a minimal reproducible example. All the visuals an the annotations are not related to your problem but render the code overly complex which makes it harder for others to work with it.
The following would be sufficient:
ggplot(df) +
geom_bar(aes(x = Year, y = Response),
stat = "identity", fill = "tan1",
colour = "black") +
geom_errorbar(aes(x = Year, ymin = Response - sd1, ymax = Response + sd1),
width = .2,
position = pd) +
geom_line(aes(x = Year, y = Rate * max(df$Response)),
color = 'red', size = 2) +
geom_point(aes(x = Year, y = Rate * max(df$Response)),
color = 'black', size = 3)
(Notice that I've removed stat = "identity" in all geom_s because this is set by default. Furthermore, y is not a valid aestetic for geom_errorbar() so I omitted that, too.)
Assuming that the additional variable you would like to plot error bars for is Rate * max(df$Response)) and that the relevant standard deviation is sd2, you may simply append
+ geom_errorbar(aes(x = Year, ymin = Rate * max(df$Response) - sd2,
ymax = Rate * max(df$Response) + sd2),
colour = "green",
width = .2)
to the code chunk above. This yields the output below.

ggplot2 bar chart tick position and custom legend issue

I have a ggplo bar chart like this
created from
library(lubridate)
library(ggplot2)
library(grid)
library(scales)
### Set up dummy data.
dayVec <- seq(ymd('2016-01-01'), ymd('2016-01-10'), by = '1 day')
dayCount <- length(dayVec)
dayValVec1 <- c(0,-0.25,0.15,0.3,0.4,0.10,0.17,0.22,0.50,0.89)
dayValVec2 <- c(0.15,0.2,-0.17,0.6,0.16,0.41,0.55,0.80,0.90,1.00)
dayValVec3 <- dayValVec2
dayDF <- data.frame(Date = rep(dayVec, 3),
DataType = factor(c(rep('A', dayCount), rep('B', dayCount), rep('C', dayCount))),
Value = c(dayValVec1, dayValVec2, dayValVec3))
p <- ggplot(dayDF,aes(Date, Value, colour = DataType)) +
theme_bw() +
ggtitle("Chart Title \n") +
scale_color_manual("",values = c("#033563", "#E1E2D2"),labels = c("xxx ", "yyy ")) +
geom_rect(aes(xmin = ymd(min(dayDF$Date)),
xmax = ymd('2016-01-06'),
ymin = -Inf,
ymax = Inf
), fill = "#E1E2D2", alpha = 0.1, colour = "#E1E2D2") +
geom_bar(stat = "identity", fill = "#033563", colour = "#033563") +
geom_hline(yintercept = 0, size = 1) +
scale_x_datetime(expand = c(0,0), labels = date_format('%b-%d'), breaks = date_breaks('1 day')) +
scale_y_continuous(expand = c(0,0), labels = percent, limits = c(min(dayDF$Value)*1.2, max(dayDF$Value)*1.2)) +
theme(axis.text.x = element_text(angle = 90),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
panel.grid.minor = element_blank(),
panel.grid.major.x = element_blank(),
panel.grid.major.y = element_line(size = 0.5, colour = "black"),
axis.line = element_line(size = 1),
axis.ticks = element_line(size = 1),
axis.text = element_text(size = 20, colour = "#033563"),
axis.title.x = element_text(hjust = 2),
plot.title = element_text(size = 40, face = "bold", colour = "#033563"),
legend.position = 'bottom',
legend.text = element_text(colour = "#033563", size = 20),
legend.key = element_blank(),
panel.border = element_rect(colour = "black", fill = NA, size = 1.5)
)
p
I have to problems now, first I want to have the goem_rect to start at 0 not centered at the first bar, the problem here seems to be the date x-axis. And secondly I would like to have a legend like this
at the bottom of the chart. I tried creating a dummy data series to get two legend entries, but it doesn't even show the legend. I would prefer if the legend could be manipulated without messing with the data. The 'yyy' legend entry should indicate what the shaded are represents. Thanks in advance, I am quite a newbie to ggplot2.
Here is a solution :
1st problem with geom_rect() due to format.
I prefered POSIXct, so I could easily modify the x axis :
geom_rect(aes(xmin = as.POSIXct("2015-12-31 12:00:00"),
xmax = as.POSIXct("2016-01-06 12:00:00"),
ymin = -Inf,
ymax = Inf,
fill = "#E1E2D2"),
color = "#E1E2D2", alpha = 0.1)
Tip : Start the "2015-12-31 12:00:00" to expand the geom_rect() and end the "2016-01-06 12:00:00" if you want to totaly fill the Jan 06.
Legend
You should use scale_fill_manual() instead of scale_color_manual()
And you have to put the fill argument inside aes for geom_rect() and geom_bar().
Code:
library(lubridate)
library(ggplot2)
library(grid)
library(scales)
dayVec <- seq(as.POSIXct('2016-01-01'), as.POSIXct('2016-01-10'), by = '1 day')
dayCount <- length(dayVec)
dayValVec1 <- c(0,-0.25,0.15,0.3,0.4,0.10,0.17,0.22,0.50,0.89)
dayValVec2 <- c(0.15,0.2,-0.17,0.6,0.16,0.41,0.55,0.80,0.90,1.00)
dayValVec3 <- dayValVec2
dayDF <- data.frame(Date = rep(dayVec, 3),
DataType = factor(c(rep('A', dayCount), rep('B', dayCount), rep('C', dayCount))),
Value = c(dayValVec1, dayValVec2, dayValVec3))
dayDF$Date = as.POSIXct(dayDF$Date)
p <- ggplot(dayDF,aes(Date, Value, colour = DataType)) +
theme_bw() +
ggtitle("Chart Title \n") +
geom_rect(aes(xmin = as.POSIXct("2015-12-31 12:00:00"),
xmax = as.POSIXct("2016-01-06 12:00:00"),
ymin = -Inf,
ymax = Inf,
fill = "#E1E2D2"),
color = "#E1E2D2", alpha = 0.1) +
geom_bar(aes(fill = "#033563"), color = "#033563", stat = "identity") +
geom_hline(yintercept = 0, size = 1) +
scale_x_datetime(expand = c(0,0), labels = date_format('%b-%d'), breaks = date_breaks('1 day')) +
scale_y_continuous(expand = c(0,0), labels = percent, limits = c(min(dayDF$Value)*1.2, max(dayDF$Value)*1.2)) +
theme(axis.text.x = element_text(angle = 90),
axis.title.x = element_blank(),
axis.title.y = element_blank(),
panel.grid.minor = element_blank(),
panel.grid.major.x = element_blank(),
panel.grid.major.y = element_line(size = 0.5, color = "black"),
axis.line = element_line(size = 1),
axis.ticks = element_line(size = 1),
axis.text = element_text(size = 20, color = "#033563"),
axis.title.x = element_text(hjust = 2),
plot.title = element_text(size = 40, face = "bold", colour = "#033563"),
legend.position = 'bottom',
legend.text = element_text(color = "#033563", size = 20),
legend.key = element_blank(),
panel.border = element_rect(color = "black", fill = NA, size = 1.5)
) +
scale_fill_manual("",values = c("#033563", "#E1E2D2"),labels = c("xxx ", "yyy "))
p
PS : I had to specify tz = "Europe/Paris" in scale_x_datetime(label = date_format()) to have correct dates, depending on location.

Resources