I have a plot like this:
library(ggplot2)
library(reshape2)
library(ggh4x)
data <- data.frame(col1=c("Sample1","Sample2","Sample3","Sample4","Sample5","Sample6"),
col2=c(0.5,0.1,0.4,0.05,0.05,0.9),
col3=c(0.6,0.1,0.3,0.1,0.1,0.8),
col4=c(0.5,0.3,0.2,0.05,0.15,0.8),
col5=c("a","a","a","b","b","b"),
col6=c("c","c","c","c","c","c"))
data2 <- melt(data)
ggplot(data=data2, aes(x = variable, y = value, fill=col1))+
geom_bar(position="stack", stat="identity")+
scale_fill_manual(values=c("#e6194B","#ffe119","#f58231","#911eb4","#42d4f4","#bfef45")) +
scale_y_continuous(expand = c(0, 0),labels = scales::percent) +
facet_nested(~col6 + ~col5, scales = "free_x",space = "free_x",switch = "x") +
ggtitle("Title") +
theme_classic() +
theme(strip.text.y = element_text(angle=0),legend.position = "right",
legend.key.size = unit(0.4, 'cm'),
axis.line = element_line(colour = "black"),
axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),
strip.placement = "outside",
strip.background = element_rect(color = "white", fill = "white"),
axis.title = element_blank()) +
guides(fill=guide_legend(title=NULL, ncol = 1)) +
xlab("X axis") +
ylab("Y axis")
Which creates a barplot like this:
Please take a look
My question is simple, how can I set y-axis starting value to 10% instead of 0% (without changing the code too much). All answers are greatly appreciated! (Similar questions are checked, without success...)
While in general not recommended for bar charts one option to "set" the starting point would be to set the limits via coord_cartesian:
library(ggplot2)
library(ggh4x)
ggplot(data = data2, aes(x = variable, y = value, fill = col1)) +
geom_bar(position = "stack", stat = "identity") +
scale_fill_manual(values = c("#e6194B", "#ffe119", "#f58231", "#911eb4", "#42d4f4", "#bfef45")) +
scale_y_continuous(expand = c(0, 0), labels = scales::percent) +
facet_nested(~ col6 + ~col5, scales = "free_x", space = "free_x", switch = "x") +
ggtitle("Title") +
theme_classic() +
theme(
strip.text.y = element_text(angle = 0), legend.position = "right",
legend.key.size = unit(0.4, "cm"),
axis.line = element_line(colour = "black"),
axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1),
strip.placement = "outside",
strip.background = element_rect(color = "white", fill = "white"),
axis.title = element_blank()
) +
guides(fill = guide_legend(title = NULL, ncol = 1)) +
xlab("X axis") +
ylab("Y axis") +
coord_cartesian(ylim = c(.1, NA))
I'm trying to create plots where the x-axis ALSO appears above the plot as well as the y-axis to the right of the plot. Both should contain the same ticks as the normal axis, but NOT the axis text. This should result in a "box" with helpful tick-marks around the plot. I would also like to have smaller ticks in-between my major ticks (that are labelled) that do not have a label. Here is a figure I made:
I also drew in pink what I would like to achieve in R:
]3
My code for this plot:
p <- p + xlab("") + ylab("") + theme(legend.position = "none") + theme(axis.ticks.length = unit(-0.25, "cm"), axis.text.x = element_text(size = 30, hjust=1)) + theme(axis.text.y = element_text(size=35, hjust = 1), strip.text = element_text(size=35), axis.title.y = element_text(size = 40), legend.text = element_text(size=30), axis.title.x = element_text(size=40), legend.title = element_text(size=45))
p <- p + theme(text = element_text(family = "Helvetica")) + scale_x_continuous(limits=c(-0.5, 25), breaks = c(0, 2, 4, 6, 8, 24)) + theme(legend.background = element_rect(color = "black", linetype = "solid")) + scale_colour_manual(values = cbpallette)
p <- p + theme(legend.key.size = unit(2.5, "cm")) + theme(axis.text.x = element_text(margin = margin(t = .5, unit = "cm")), axis.text.y = element_text(margin = margin(r = .5, unit = "cm")))
p
*** Edit ***
Here is updated code, using Stefans advise. The figure looks like so, the ticks are there, the axis are missing:
p <- p + xlab("") + ylab("") + theme(legend.position = "none") + theme(axis.ticks.length = unit(-0.25, "cm"), axis.text.x = element_text(size = 30, hjust=1)) + theme(axis.text.y = element_text(size=35, hjust = 1, angle=45), strip.text = element_text(size=35), axis.title.y = element_text(size = 40), legend.text = element_text(size=30), axis.title.x = element_text(size=40))
p <- p + theme(text = element_text(family = "Helvetica")) + scale_colour_manual(values = cbpallette)
p <- p + theme(axis.text.x = element_text(margin = margin(t = .5, unit = "cm")), axis.text.y = element_text(margin = margin(r = .5, unit = "cm")))
p
You could duplicate the axes using argument sec.axis = dup_axis() for both scales like so:
library(ggplot2)
ggplot(mtcars, aes(hp, mpg)) +
geom_point() +
scale_x_continuous(sec.axis = dup_axis(name = NULL, labels = NULL)) +
scale_y_continuous(sec.axis = dup_axis(name = NULL, labels = NULL))
I have tried any method online but the legend is not automatically showing up. Some previous issue says the usage of dataframe in ggplot2 is not preferable, but I have tried together() method and it doesn't work either. How to fix the bug?
Here is the data:
library(ggplot2)
library(gtable)
R = 0.01*c(7.000, 6.800, 6.620, 6.460, 6.330, 6.250, 6.200, 6.160, 6.125, 6.100)
Maturity = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
c = seq(from=0, to=0, length.out = length(R))
for (i in 1:length(R)){
for (j in 1:i){
c[i] = c[i] + 1/(1+R[j])^Maturity[j]
}
c[i] = (1-1/(1+R[i])^Maturity[i])/c[i]
}
Forward = seq(from=0, to=0, length.out = length(R))
for (i in 1:length(R)){
Forward[i] = (1+R[i+1])^2/(1+R[i])-1
}
Here is the plot code in RMarkDown:
```{R fig.width=2.7559, fig.height=2.0669291}
df = data.frame(Maturity=Maturity, ParYield=c, ForwardRate=Forward, R=R)
p = ggplot(data=df, aes(x=Maturity, y=ParYield)) +
ggtitle("Curve of Zero-coupon Yield, Par Yield, Forward Yield")+
labs(x = "Maturity (year)", y = "Par Yield") +
scale_y_continuous(breaks=seq(100*(min(na.omit(Forward), c)-0.01),
100*(max(na.omit(Forward),c)+0.01),by=0.1)/100,
sec.axis = dup_axis(),
labels = scales::number_format(accuracy = 0.005)) +
scale_x_continuous("Maturity", labels=as.character(Maturity), breaks=Maturity,
sec.axis = dup_axis()) +
theme_classic() +
geom_line(aes(y=ParYield), size=1) +
geom_line(aes(y=R), size=1) +
geom_line(aes(y=ForwardRate), size=1) +
geom_point(aes(y=ParYield), shape=21, fill=rgb(69/255, 117/255, 180/255),
size=3, stroke=1.5, color="black") +
geom_point(aes(y=R), shape=22, fill=rgb(145/255, 191/255, 219/255),
size=3, stroke=1.5, color="black") +
geom_point(aes(y=ForwardRate), shape=23, fill=rgb(224/255, 243/255, 248/255),
size=3, stroke=1.5, color="black") +
theme(plot.title = element_text(size=14, hjust=0.5),
text = element_text(size=15, colour = "black", family = "Calibri"),
axis.ticks.length = unit(-0.25, 'cm'),
axis.line = element_line(size=1),
axis.ticks = element_line(size=1),
axis.text.x = element_text(margin = margin(t=15)),
axis.text.x.top = element_text(margin = margin(b=15)),
axis.text.y.right = element_text(margin = margin(l=15, r=5)),
axis.text.y = element_text(margin = margin(l=5, r=15)),
axis.title.x.top = element_blank(),
axis.title.y.right = element_blank())+
guides(colour=guide_legend(override.aes = list(pch=c(16,21,20),fill=c('r','r','r'))))+
theme(legend.position = c(0.8,0.8), legend.justification = c("right", "top"))
p
Check this sketch and make the necessary adjustments as I am not clear on how colors must be set. Pay attention to the suggestion from #stefan and modify next code:
library(ggplot2)
#Code
df = data.frame(Maturity=Maturity, ParYield=c, ForwardRate=Forward, R=R)
ggplot(data=df, aes(x=Maturity, y=ParYield)) +
ggtitle("Curve of Zero-coupon Yield, Par Yield, Forward Yield")+
labs(x = "Maturity (year)", y = "Par Yield") +
scale_y_continuous(breaks=seq(100*(min(na.omit(Forward), c)-0.01),
100*(max(na.omit(Forward),c)+0.01),by=0.1)/100,
sec.axis = dup_axis(),
labels = scales::number_format(accuracy = 0.005)) +
scale_x_continuous("Maturity", labels=as.character(Maturity), breaks=Maturity,
sec.axis = dup_axis()) +
theme_classic() +
geom_line(aes(y=ParYield), size=1) +
geom_line(aes(y=R), size=1) +
geom_line(aes(y=ForwardRate), size=1) +
geom_point(aes(y=ParYield,colour='ParYield'), shape=21, fill=rgb(69/255, 117/255, 180/255),
size=3, stroke=1.5,show.legend = T) + #Black
geom_point(aes(y=R,colour='R'), shape=22,
fill=rgb(145/255, 191/255, 219/255),
size=3, stroke=1.5) + #Black
geom_point(aes(y=ForwardRate,colour='ForwardRate'), shape=23,
fill=rgb(224/255, 243/255, 248/255),
size=3, stroke=1.5) +
theme(plot.title = element_text(size=14, hjust=0.5),
text = element_text(size=15, colour = "black", family = "Calibri"),
axis.ticks.length = unit(-0.25, 'cm'),
axis.line = element_line(size=1),
axis.ticks = element_line(size=1),
axis.text.x = element_text(margin = margin(t=15)),
axis.text.x.top = element_text(margin = margin(b=15)),
axis.text.y.right = element_text(margin = margin(l=15, r=5)),
axis.text.y = element_text(margin = margin(l=5, r=15)),
axis.title.x.top = element_blank(),
axis.title.y.right = element_blank())+
guides(colour=guide_legend(override.aes = list(pch=c(16,21,20))))+
theme(legend.position = c(0.8,0.8), legend.justification = c("right", "top"))+
labs(color='Variable')
Output:
Other option would be:
#Code 2
df = data.frame(Maturity=Maturity, ParYield=c, ForwardRate=Forward, R=R)
ggplot(data=df, aes(x=Maturity, y=ParYield)) +
ggtitle("Curve of Zero-coupon Yield, Par Yield, Forward Yield")+
labs(x = "Maturity (year)", y = "Par Yield") +
scale_y_continuous(breaks=seq(100*(min(na.omit(Forward), c)-0.01),
100*(max(na.omit(Forward),c)+0.01),by=0.1)/100,
sec.axis = dup_axis(),
labels = scales::number_format(accuracy = 0.005)) +
scale_x_continuous("Maturity", labels=as.character(Maturity), breaks=Maturity,
sec.axis = dup_axis()) +
theme_classic() +
geom_line(aes(y=ParYield), size=1) +
geom_line(aes(y=R), size=1) +
geom_line(aes(y=ForwardRate), size=1) +
geom_point(aes(y=ParYield,colour='ParYield'), shape=21,
fill=rgb(69/255, 117/255, 180/255),
size=3, stroke=1.5,show.legend = T) +
geom_point(aes(y=R,colour='R'), shape=22,
fill=rgb(145/255, 191/255, 219/255),
size=3, stroke=1.5) +
geom_point(aes(y=ForwardRate,colour='ForwardRate'), shape=23,
fill=rgb(224/255, 243/255, 248/255),
size=3, stroke=1.5) +
scale_color_manual(values = c('black','black','black'))+
theme(plot.title = element_text(size=14, hjust=0.5),
text = element_text(size=15, colour = "black", family = "Calibri"),
axis.ticks.length = unit(-0.25, 'cm'),
axis.line = element_line(size=1),
axis.ticks = element_line(size=1),
axis.text.x = element_text(margin = margin(t=15)),
axis.text.x.top = element_text(margin = margin(b=15)),
axis.text.y.right = element_text(margin = margin(l=15, r=5)),
axis.text.y = element_text(margin = margin(l=5, r=15)),
axis.title.x.top = element_blank(),
axis.title.y.right = element_blank())+
guides(colour=guide_legend(override.aes = list(pch=c(16,21,20))))+
theme(legend.position = c(0.8,0.8), legend.justification = c("right", "top"))+
labs(color='Variable')
Output:
You need to map some additional aesthetics to variables in your data. I accomplished this by pivoting your data to a longer format.
library(tidyr)
df2 <- df %>% pivot_longer(-Maturity, names_to = "Yield", values_to = "Rate")
Then, I only used one geom_line and one geom_point, but with the new Yield variable mapped to group, fill, and shape. Now you can use scale_shape_manual and scale_fill_manual to set the appearances the way you want.
p = ggplot(data=df2, aes(x = Maturity, y = Rate, group = Yield,
fill = Yield, shape = Yield)) +
ggtitle("Curve of Zero-coupon Yield, Par Yield, Forward Yield")+
labs(x = "Maturity (year)", y = "Yield") +
scale_y_continuous(breaks=seq(100*(min(na.omit(Forward), c)-0.01),
100*(max(na.omit(Forward),c)+0.01),by=0.1)/100,
sec.axis = dup_axis(),
labels = scales::number_format(accuracy = 0.005)) +
scale_x_continuous("Maturity", labels=as.character(Maturity), breaks=Maturity,
sec.axis = dup_axis()) +
theme_classic() +
geom_line(size=1) +
geom_point(size=3, stroke=1.5, color="black") +
scale_shape_manual(values = c("ParYield" = 21, "R" = 22, "ForwardRate" = 23),
labels = c("Par Yield", "Zero-coupon Yield", "Forward Yield")) +
scale_fill_manual(values = c("ParYield" = rgb(69/255, 117/255, 180/255),
"R" = rgb(145/255, 191/255, 219/255),
"ForwardRate" = rgb(224/255, 243/255, 248/255)),
labels = c("Par Yield", "Zero-coupon Yield", "Forward Yield")) +
theme(plot.title = element_text(size=14, hjust=0.5),
text = element_text(size=15, colour = "black", family = "Calibri"),
axis.ticks.length = unit(-0.25, 'cm'),
axis.line = element_line(size=1),
axis.ticks = element_line(size=1),
axis.text.x = element_text(margin = margin(t=15)),
axis.text.x.top = element_text(margin = margin(b=15)),
axis.text.y.right = element_text(margin = margin(l=15, r=5)),
axis.text.y = element_text(margin = margin(l=5, r=15)),
axis.title.x.top = element_blank(),
axis.title.y.right = element_blank())+
guides(colour=guide_legend(override.aes = list(pch=c(16,21,20),fill=c('r','r','r'))))+
theme(legend.position = c(0.8,0.8), legend.justification = c("right", "top"))
I would recommend rethinking your y axis labels.'
By running this code :
g <- ggplot(results_table, aes(x = "", y = Pct*100,
fill = factor(results_table$Criteria, as.character(results_table$Criteria))),width = 0.5) +
geom_bar(stat = "identity") +
scale_color_manual(values = Palcolor) +
scale_fill_manual(values = Palcolor) +
coord_polar(theta = "y", start = 0, direction = -1) +
theme_minimal() +
theme(legend.position = "bottom", legend.title=element_blank(), axis.title.x = element_blank(),,
axis.title.y = element_blank(), panel.border = element_blank(), panel.grid = element_blank(),
axis.text = element_blank(), axis.ticks = element_blank(),
plot.title = element_text(size = 14, hjust = 0.5, vjust = 0)) +
guides(fill = guide_legend(nrow = 4, byrow = TRUE)) +
theme(
legend.key.height = unit(0.3, "lines"), #smaller squares
legend.key.width = unit(0.7, "lines"), #smaller squares
legend.margin=margin(l = 40, unit='pt'),
legend.text = element_text(margin = margin(r = 60, unit = "pt"))) +
xlab("") +
ylab("") +
geom_text(aes(x = 1.70, y =Pct*100/2 + c(0, cumsum(Pct*100)[-length(Pct*100)]),
label = paste0(sprintf("%0.1f", round(Pct*100, digits = 1)),"%")),
size = 3.2) +
labs(title = gTitle)
}
I get this pie chart :
As you can see, the slices and the color are right, but the labels are reversed. If I use
position = position_stack (vjust = 0.5, reverse = TRUE)
in geom_text, it reduces the whole pie to a small slice, then it doesn't fix my issue.
The solution is to substract the result of the formula for y in geom_text from 100 :
`geom_text(aes(x = 1.70, y = 100-(Pct*100/2 + c(0, cumsum(Pct*100)[-length(Pct*100)])),
label = paste0(sprintf("%0.1f", round(Pct*100, digits = 1)),"%")),
size = 3.2)'
I have run the following code :`
g <- ggplot(results_table, aes(x = "", y = Pct*100, fill = Criteria),width = 1) +
geom_bar(stat = "identity", color = Palcolor, fill = Palcolor) +
coord_polar(theta = "y", start = 0) +
theme_minimal() +
theme(legend.position = "bottom", legend.title=element_blank(), axis.title.x = element_blank(),,
axis.title.y = element_blank(), panel.border = element_blank(), panel.grid = element_blank(),
axis.text = element_blank(), axis.ticks = element_blank(),
plot.title = element_text(size = 14, hjust = 0.5, vjust = 0)) +
guides(fill = guide_legend(nrow = 4, byrow = TRUE)) +
theme(
legend.key.height = unit(0.3, "lines"), #smaller squares
legend.key.width = unit(0.7, "lines"), #smaller squares
legend.margin=margin(l = 40, unit='pt'),
legend.text = element_text(margin = margin(r = 60, unit = "pt"))) +
xlab("") +
ylab("") +
geom_text(aes(x = 1.70, y = Pct*100/2 + c(0, cumsum(Pct*100)[-length(Pct*100)]),
label = paste0(sprintf("%0.1f", round(Pct*100, digits = 1)),"%")),
size = 3.2) +
labs(title = gTitle)
}`
It created the pie chart as expected, but not the customized legend :
Any idea ?
The problem is that you set the custom color and fill palettes as arguments inside geom_bar. This way no legend will show up. You have to use scale_color/fill_manual to set the color palettes for the color/fill aesthetics.
Using ggplot2::mpg as example data and an example palette from RColorBrewer try this:
library(ggplot2)
library(dplyr)
# Example data
results_table <- mpg %>%
count(class) %>%
mutate(Pct = n / sum(n),
class = reorder(class, Pct)) %>%
rename(Criteria = class) %>%
arrange(desc(Pct)) %>%
mutate()
# Example palette as named vector to get the colors and categories right
Palcolor <- c("2seater" = "#8DD3C7", "minivan" = "#FFFFB3", "pickup" = "#BEBADA", "subcompact" = "#FB8072", "midsize" = "#80B1D3", "compact" = "#FDB462", "suv" = "#B3DE69")
# Example title
gTitle = "Example title"
g <- ggplot(results_table, aes(x = "", y = Pct*100, fill = Criteria),width = 1) +
geom_bar(stat = "identity") +
scale_color_manual(values = Palcolor) +
scale_fill_manual(values = Palcolor) +
coord_polar(theta = "y", start = 0) +
theme_minimal() +
theme(legend.position = "bottom", legend.title=element_blank(), axis.title.x = element_blank(),,
axis.title.y = element_blank(), panel.border = element_blank(), panel.grid = element_blank(),
axis.text = element_blank(), axis.ticks = element_blank(),
plot.title = element_text(size = 14, hjust = 0.5, vjust = 0)) +
guides(fill = guide_legend(nrow = 4, byrow = TRUE)) +
theme(
legend.key.height = unit(0.3, "lines"), #smaller squares
legend.key.width = unit(0.7, "lines"), #smaller squares
legend.margin=margin(l = 40, unit='pt'),
legend.text = element_text(margin = margin(r = 60, unit = "pt"))) +
xlab("") +
ylab("") +
geom_text(aes(x = 1.70, y = Pct*100/2 + c(0, cumsum(Pct*100)[-length(Pct*100)]),
label = paste0(sprintf("%0.1f", round(Pct*100, digits = 1)),"%")),
size = 3.2) +
labs(title = gTitle)
g
Created on 2020-05-16 by the reprex package (v0.3.0)