R + ggplot2 => add labels on facet pie chart [duplicate] - r

This question already has answers here:
ggplot, facet, piechart: placing text in the middle of pie chart slices
(4 answers)
Closed 7 years ago.
I want to add data labels on faceted pie char.
Maybe someone can can help me.
My data:
year <- c(1,2,1,2,1,2)
prod <- c(1,1,2,2,3,3)
quantity <- c(33,50,33,25,34,25)
df <- data.frame(year, prod, quantity)
rm(year, prod, quantity)
Code:
library(ggplot2)
# center's calculated by hand
centr2 <- c(16, 25, 49, 62.5, 81, 87.5)
ggplot(data=df, aes(x=factor(1), y=quantity, fill=factor(prod))) +
geom_bar(stat="identity") +
geom_text(aes(x= factor(1), y=centr2, label = df$quantity), size=10) +
facet_grid(facets = .~year, labeller = label_value) +
coord_polar(theta = "y")
And my result is:
If I remove coord_polar(theta = "y"), I will have the following plot:
And now it is clear for me, why my data labels did not match.
But I don't know how to fix it.
I read:
1. Place labels on Pie Chart
2. Add text to ggplot with facetted densities
3. Pie plot getting its text on top of each other
But didn't find the answer.

I would approach this by defining another variable (which I call pos) in df that calculates the position of text labels. I do this with dplyr but you could also use other methods of course.
library(dplyr)
library(ggplot2)
df <- df %>% group_by(year) %>% mutate(pos = cumsum(quantity)- quantity/2)
ggplot(data=df, aes(x=factor(1), y=quantity, fill=factor(prod))) +
geom_bar(stat="identity") +
geom_text(aes(x= factor(1), y=pos, label = quantity), size=10) + # note y = pos
facet_grid(facets = .~year, labeller = label_value) +
coord_polar(theta = "y")

Related

How can I make stacked dot plots using a facet in GGplot2? R

I am trying to stack dot plots using a facet in GGplot2.
My first dot plot:
plot1 <- ggplot(marathon, aes(x = MarathonTime, y = first_split_percent)) +
geom_point()
plot1
My second:
plot2 <- ggplot(marathon, aes(x=MarathonTime, y=km4week)) +
geom_point()
plot2
I am trying to stack them on top of each other as they share the same x-axis. I have tried using facet_wrap as so:
plot3 <- ggplot(marathon, aes(x = MarathonTime, y = first_split_percent)) +
geom_point() +
facet_wrap(km4week~.)
plot3
I have also played around with the 'rows = vars(km4week), cols = vars(MarathonTime)' functions but have had no luck. Is there a way to achieve what I am describing without a facet? Or am I using the Facet function incorrectly? Any help is greatly appreciated!
To stack your two plots using facetting you first have to reshape your data so that your columns become categories of one column or variable which could then be used in facet_wrap.
Using some fake random example data:
set.seed(123)
marathon <- data.frame(
MarathonTime = runif(100, 2, 4),
first_split_percent = runif(100, 45, 55),
km4week= runif(100, 20, 140)
)
library(ggplot2)
library(tidyr)
marathon_long <- marathon |>
pivot_longer(c(first_split_percent, km4week), names_to = "variable")
ggplot(marathon_long, aes(x = MarathonTime, y = value)) +
geom_point() +
facet_wrap(~variable, scales = "free_y", strip.position = "right", ncol = 1)

Keeping unit of measure in facet_wrap while scales="free_y"? [duplicate]

This question already has an answer here:
Setting individual y axis limits with facet wrap NOT with scales free_y
(1 answer)
Closed 4 years ago.
I'm trying to create a facet_wrap() where the unit of measure remains identical across the different plots, while allowing to slide across the y axis.
To clearify with I mean, I have created a dataset df:
library(tidyverse)
df <- tibble(
Year = c(2010,2011,2012,2010,2011,2012),
Category=c("A","A","A","B","B","B"),
Value=c(1.50, 1.70, 1.60, 4.50, 4.60, 4.55)
)
with df, we can create the following plot using facet_wrap:
ggplot(data = df, aes(x=Year, y=Value)) + geom_line() + facet_wrap(.~ Category)
Plot 1
To clarify the differences between both plots, one can use scale = "free_y":
ggplot(data = df, aes(x=Year, y=Value)) + geom_line()
+ facet_wrap(.~ Category, scale="free_y")
Plot 2
Although it's more clear, the scale on the y-axis in plot A isequal to 0.025, while being 0.0125 in B. This could be misleading to someone who's comparing A & B next to each other.
So my question right now is to know whether there exist an elegant way of plotting something like the graph below (with y-scale = 0.025) without having to plot two seperate plots into a grid?
Thanks
Desired result:
Code for the grid:
# Grid
## Plot A
df_A <- df %>%
filter(Category == "A")
plot_A <- ggplot(data = df_A, aes(x=Year, y=Value)) + geom_line() + coord_cartesian(ylim = c(1.5,1.7)) + ggtitle("A")
## Plot B
df_B <- df %>%
filter(Category == "B")
plot_B <- ggplot(data = df_B, aes(x=Year, y=Value)) + geom_line() + coord_cartesian(ylim = c(4.4,4.6)) + ggtitle("B")
grid.arrange(plot_A, plot_B, nrow=1)
Based on the info at Setting individual y axis limits with facet wrap NOT with scales free_y you can you use geom_blank() and manually specified y-limits by Category:
# df from above code
df2 <- tibble(
Category = c("A", "B"),
y_min = c(1.5, 4.4),
y_max = c(1.7, 4.6)
)
df <- full_join(df, df2, by = "Category")
ggplot(data = df, aes(x=Year, y=Value)) + geom_line() +
facet_wrap(.~ Category, scales = "free_y") +
geom_blank(aes(y = y_min)) +
geom_blank(aes(y = y_max))

Plotting a bar chart with years grouped together

I am using the fivethirtyeight bechdel dataset, located here https://github.com/rudeboybert/fivethirtyeight, and am attempting to recreate the first plot shown in the article here https://fivethirtyeight.com/features/the-dollar-and-cents-case-against-hollywoods-exclusion-of-women/. I am having trouble getting the years to group together similarly to how they did in the article.
This is the current code I have:
ggplot(data = bechdel, aes(year)) +
geom_histogram(aes(fill = clean_test), binwidth = 5, position = "fill") +
scale_fill_manual(breaks = c("ok", "dubious", "men", "notalk", "nowomen"),
values=c("red", "salmon", "lightpink", "dodgerblue",
"blue")) +
theme_fivethirtyeight()
I see where you were going with using the histogram geom but this really looks more like a categorical bar chart. Once you take that approach it's easier, after a bit of ugly code to get the correct labels on the year columns.
The bars are stacked in the wrong order on this one, and there needs to be some formatting applied to look like the 538 chart, but I'll leave that for you.
library(fivethirtyeight)
library(tidyverse)
library(ggthemes)
library(scales)
# Create date range column
bechdel_summary <- bechdel %>%
mutate(date.range = ((year %/% 10)* 10) + ((year %% 10) %/% 5 * 5)) %>%
mutate(date.range = paste0(date.range," - '",substr(date.range + 5,3,5)))
ggplot(data = bechdel_summary, aes(x = date.range, fill = clean_test)) +
geom_bar(position = "fill", width = 0.95) +
scale_y_continuous(labels = percent) +
theme_fivethirtyeight()
ggplot

R percent labels on pie chart [duplicate]

This question already has answers here:
pie chart with ggplot2 with specific order and percentage annotations
(2 answers)
Closed 5 years ago.
I'm trying to add some percent labels to a pie chart but any of the solutions works. The thing is that the chart displays the number of tasks completed grouped by category.
output$plot2<-renderPlot({
ggplot(data=data[data$status=='100% completed',], aes(x=factor(1), fill=category))+
geom_bar(width = 1)+
coord_polar("y")
Using geom_text with position_stack to adjust the label locations would work.
library(ggplot2)
library(dplyr)
# Create a data frame which is able to replicate your plot
plot_frame <- data.frame(category = c("A", "B", "B", "C"))
# Get counts of categories
plot_frame <- plot_frame %>%
group_by(category) %>%
summarise(counts = n()) %>%
mutate(percentages = counts/sum(counts)*100)
# Plot
ggplot(plot_frame, aes(x = factor(1), y = counts)) +
geom_col(aes(fill = category), width = 1) +
geom_text(aes(label = percentages), position = position_stack(vjust = 0.5)) +
coord_polar("y")
The codes above generate this:
You might want to change the y-axis from counts to percentages since you are labeling the latter. In that case, change the values passed to ggplot accordingly.

Split data to plot histograms side-by-side in R

I am learning R with the Australian athletes data set.
By using ggplot, I can plot a histogram like this.
library(DAAG)
ggplot(ais, aes(wt, fill = sex)) +
geom_histogram(binwidth = 5)
By using summary(ais$wt), the 3rd Quartile is 84.12. Now I want to split the data by the wt 84.12. and plot 2 similar histograms accordingly (side by side)
The split is:
ais1 = ais$wt[which(ais$wt>=0 & ais$wt<=84.12)]
ais2 = ais$wt[which(ais$wt>84.12)]
But I don’t know how to fit them in the plotting. I tried but it doesn't work:
ggplot(ais1, aes(wt, fill = sex)) +...
How can I plot the histograms (2 similar histograms accordingly, side by side)?
Add the split as a column to your data
ais$wt_3q = ifelse(ais$wt < 84.12, "Quartiles 1-3", "Quartile 4")
Then use facets:
ggplot(ais, aes(wt, fill = sex)) +
geom_histogram(binwidth = 5) +
facet_wrap(~ wt_3q)
The created variable is a factor, if you specify the order of the levels you can order the facets differently (lots of questions on here showing that if you search for them - same as reordering bars for a ggplot barplot). You can also let the scales vary - look at ?facet_wrap for more details.
Generally, you shouldn't create more data frames. Creating ais1 and ais2 is usually avoidable, and your life will be simpler if you use a single data frame for a single data set. Adding a new column for grouping makes it easy to keep things organized.
We can do this with ggarrange to arrange the plot objects for each subset
library(DAAG)
library(ggplot2)
library(ggpubr)
p2 <- ais %>%
filter(wt>=0, wt<=84.12) %>%
ggplot(., aes(wt, fill = sex)) +
geom_histogram(binwidth = 5) +
coord_cartesian(ylim = c(0, 30))
p1 <- ais %>%
filter(wt>84.12) %>%
ggplot(., aes(wt, fill = sex)) +
geom_histogram(binwidth = 5) +
coord_cartesian(ylim = c(0, 30))
ggarrange(p1, p2, ncol =2, nrow = 1, labels = c("p1", "p2"))
-output

Resources