ggplot - dual line chart and stacked bar chart on one plot - r

My data consists of a date variable and four numeric variables, of the 4 numeric variables I wish to plot two of these as a stacked bar chart and the remaining variables as line charts.
Is it possible to create two line charts and a stacked bar chart in a single plot using ggplot?
My data looks as follows:
data <- tibble(Month = 1:12,Brands = c(1,1,1,1,1,1,2,2,2,2,2,2),Generics = Brands + 1,Metric1 = c(5,5,5,5,5,5,6,6,7,8,9,10),Metric2 = c(10,10,11,11,12,13,14,15,16,17,18,19))
I wish to plot months on the x axis, Brands1 & Brands2 as stacked bar charts and Metric1 & Metric2 as line charts all on the same chart if possible.

Something like this?
library(tidyverse)
data <- tibble(Month = 1:12,Brands = c(1,1,1,1,1,1,2,2,2,2,2,2),Generics = Brands + 1,Metric1 = c(5,5,5,5,5,5,6,6,7,8,9,10),Metric2 = c(10,10,11,11,12,13,14,15,16,17,18,19))
data %>%
pivot_longer(cols = c(Brands,Generics)) %>%
pivot_longer(cols = c(Metric1,Metric2),
names_to = "metric_name",values_to = "metric_value") %>%
ggplot(aes(Month))+
geom_col(aes(y = value, fill = name))+
geom_line(aes(y = metric_value, col = metric_name),size = 1.25)+
scale_x_continuous(breaks = 1:12)+
scale_color_manual(values = c("black","purple"))

Related

Variable distances between bars on ggplot bar plot

I have the following bar plot created using R ggplot. How do I dynamically update the distances between the bars on the plot using the 'distance' column of the same data frame.
library(tidyverse)
data.frame(name = c("A","B","C","D","E"),
value = c(34,45,23,45,75),
distance = c(3,4,1,2,5)) %>%
ggplot(aes(x = name, y = value)) +
geom_col()

Error bars on stacked barchart, using either plotly or ggplotly

I need to convert into widget a simple ggplot, a stacked bar with uncertainty.
The data:
world.tot <- data.frame('country'='world', 'GHG'=c('CH4', 'CO2','N2O'),
'emi'=c(6e+6, 3e+6, 1+6),
'unc.min'=8561406, 'unc.max'=14027350)
and the ggplot:
p2 <- ggplot(world.tot) +
geom_bar(aes(x=country,y=emi,fill=GHG), stat='identity', position='stack' ) +
geom_errorbar(aes(x=country, ymin=unc.min, ymax=unc.max), width=0.2) +
theme(axis.title. x=element_blank(), axis.title. y=element_blank()) +
theme(legend.position='none')
When I try: ggplotly(p2) only the stacked bars are converted, not the error bar. Any advice?
Alternatively, I could use plot_ly to create the plot, but cannot manage to add the error bar:
plot_ly(world.tot, x=~country. y=~emi, color=~GHG,type=bar,
error_y=~list(array(c(unc.min, unc.max))) %>%
layout(barmode='stack')
This produces error bars to all shares of the stacked histogram, while I need only one error at the top of the stacked histogram.
Any help is appreciated
You can prepare a data.frame that has only one error size per group
library(dplyr)
world.err <- world.tot %>%
group_by(country) %>%
summarise(emi = sum(emi), unc.min = 8561406, unc.max = 14027350)
And plot the errors as a separate trace
plot_ly(world.tot) %>%
add_bars(x = ~country, y = ~emi, color = ~GHG, type='bar') %>%
add_trace(x = ~country, y = ~emi, data = world.err,
showlegend = F, mode='none', type='scatter',
error_y = ~list(array = c(unc.min, unc.max), color = '#000000')) %>%
layout(barmode='stack')

R: Plotting with ggplot using multiple lines

so I'm trying to Plot chart. I filtered the original dataset Datengf to get the median income of each year (MULTYEAR) and the variable Schulbildung. No chart looks like this: chart. Now I want to plot chart by using ggplot and geom_line. On the x-axis MULTYEAR and on the y-axis the medianincome. But I want it to be a different line and color for each value of Schulbildung.
Chart code:
chart <- Datengf %>%
filter(SEX == 1)%>%
group_by(MULTYEAR,Schulbildung) %>%
summarise(medianincome = median(INCWAGE))%>%
ungroup()%>%
mutate(Schulbildung = ifelse(Schulbildung < 12, "others", Schulbildung)) %>%
group_by(Schulbildung,MULTYEAR)%>%
summarise(medianincome = sum(medianincome))
I tried using
chartplot <- chart %>%
ggplot(aes(x = MULTYEAR, y = medianincome))+
geom_line()
but the chart is an complete mess.
Specify color in the aes function:
chartplot <- chart %>%
ggplot(aes(x = MULTYEAR, y = medianincome, color = Schulbildung))+
geom_line()

Adding points, symbols, and legends to ggplot

I have created a plot using ggplot (with DF1 dataset below). I would like two additions to this plot:
to add symbol based on DF.SYMBOL dataset (on specified times for two IDs: different shape and color by event).
to add a vertical line within the bar with CONC as legend based on DF.LINE dataset
I would appreciate your suggestion!
ID<-rep(c(1,2),each=6)
START <- c(0, 42,57,300,520,710, 0,31,56,85,120,300)
END <- c(42,57,300,520,710,711,31,56,85,120,300,301)
TYPE <- c("S","NR","R","NR","R","R","S","R","NR","R","NR","NR")
DF1 <-data.frame(ID,START,END,TYPE)
DF1
# converting ID from numeric to factor
DF1 %<>%
dplyr::mutate(ID = factor(ID))
ggplot(DF1,aes(y=ID,yend=ID,x=START,xend=END,color=TYPE))+
geom_segment(aes(y=ID,yend=ID,x=START,xend=END),size=6,lineend= "butt")
DF.SYMBOL dataset to add points and symbols to the plot
ID<-rep(c(1,2),each=2)
EVENT <- rep(c("TBR","PBR"))
TIME <- c(90, 220,120,200)
DF.SYMBOL<-data.frame(ID,EVENT,TIME)
DF.LINE dataset to add a vertical line in bar with CONC in legend above the vertical line for each ID
ID <- c(1,2)
TIME <- c(400, 265)
CONC <- c(23,97)
DF.LINE<-data.frame(ID,TIME, CONC)
Here's the desired plot (edited on powerpoint): symbols based on DF.SYMBOL dataset and black line with value based on DF.LINE dataset.
This should do it. I used geom_errorbarh for the vertical line - I don't know a better way to get a vertical line across a horizontal bar on a discrete scale. For better control of the thickness you might consider changing the geom_segment to a geom_rect.
DF.SYMBOL$ID = factor(DF.SYMBOL$ID)
DF.LINE$ID = factor(DF.LINE$ID)
ggplot(DF1,aes(y=ID))+
geom_segment(aes(yend=ID, x=START, xend=END, color = TYPE),size=6,lineend= "butt") +
geom_point(data = DF.SYMBOL, aes(x = TIME, fill = EVENT, shape = EVENT), size = ) +
scale_shape_manual(values = c(21, 24)) +
scale_fill_manual(values = c("red", "yellow")) +
geom_errorbarh(data = DF.LINE, aes(xmin = TIME, xmax = TIME), height = 0.1) +
geom_text(data = DF.LINE, aes(x = TIME, label = CONC), vjust = -1.5)

faceted piechart with ggplot

I have the following data.frame:
x = data.frame(category=c(1,1,1,1,2,2,2,2), value=c(1,2,1,1,2,2,2,1));
x$category = as.factor(x$category);
x$value = as.factor(x$value);
and I have created a faceted bar chart with ggplot2.
ggplot(x, aes(value, fill=category)) + geom_bar() + facet_wrap(~category);
However, I would like to have a pie chart that shows the fraction values (based on the totals for each category). The diagram should then show one pie chart for each category and two fractions inside each pie chart, one for each value factor. The real data has up to 6 categories and I have a few 1000 data sets). Is there a generic way to do that?
One way is to calculate the percentage/ratio beforehand and then use it to get the position of the text label. See also how to put percentage label in ggplot when geom_text is not suitable?
# Your data
y = data.frame(category=c(1,1,1,1,2,2,2,2), value=c(2,2,1,1,2,2,2,1))
# get counts and melt it
data.m = melt(table(y))
names(data.m)[3] = "count"
# calculate percentage:
m1 = ddply(data.m, .(category), summarize, ratio=count/sum(count))
#order data frame (needed to comply with percentage column):
m2 = data.m[order(data.m$category),]
# combine them:
mydf = data.frame(m2,ratio=m1$ratio)
# get positions of percentage labels:
mydf = ddply(mydf, .(category), transform, position = cumsum(count) - 0.5*count)
# create bar plot
pie = ggplot(mydf, aes(x = factor(1), y = count, fill = as.factor(value))) +
geom_bar(stat = "identity", width = 1) +
facet_wrap(~category)
# make a pie
pie = pie + coord_polar(theta = "y")
# add labels
pie + geom_text(aes(label = sprintf("%1.2f%%", 100*ratio), y = position))

Resources