I have a csv file that looks like this:
Specialty, Recording 1, Recording 2, Recording 3
A, 100%, 200%, 300%
B, 50%, -75%, 150%
C, 60%, 100%, -25%
I would like to plot them on a graph so that it looks like this:
I believe I can do so with this:
ggplot(data2, aes(x=Recording 1, y=Specialty)) + geom_point()
How do I add Recording 2 and 3 to the same graph?
If that is example what the data looks like, I recreated it here for my answer.
Example data
structure(list(Specialty = structure(1:3, .Label = c("A", "B",
"C"), class = "factor"), Recording.1 = structure(1:3, .Label = c("100%",
"50%", "60%"), class = "factor"), Recording.2 = structure(c(3L,
1L, 2L), .Label = c("-75%", "100%", "200%"), class = "factor"),
Recording.3 = structure(3:1, .Label = c("-25%", "150%", "300%"
), class = "factor")), class = "data.frame", row.names = c(NA,
-3L))
First, since the data has %'s you will need to remove that. ggplot needs numeric values to plot. NOTE: since you columns titles have spaces in them they need to be in
df$`Recording 1` <- as.numeric(sub("%", "", df$`Recording 1`))
df$`Recording 2` <- as.numeric(sub("%", "", df$`Recording 2`))
df$`Recording 3` <- as.numeric(sub("%", "", df$`Recording 3`))
library(ggplot2)
library(reshape2)
You can then use reshape2 so you can plot everyone together.
df <- melt(df, id.vars='Specialty')
After that, you should be good to go to make the plot
ggplot(df, aes(x=value, y=Specialty, fill=variable, color=variable)) + geom_point(stat='identity') + scale_x_continuous(name = "whatever (%)", limit = c(-100, 300))
or to add percent in the x-axis
library(scales)
ggplot(df, aes(x=value, y=Specialty, fill=variable, color=variable)) + geom_point(stat='identity') + scale_x_continuous(labels = percent_format(scale = 1), name = "whatever (%)", limit = c(-100, 300))
Here is the output
With percents in x-axis
I've made you an example data set. I've assumed you don't have the "%" in the dataset and the fields are numeric. We add the "%" to the x-axis label using the scales package. Point here is to first make your data long with pivot_longer.
library(dplyr)
library(tidyr)
library(ggplot2)
library(scales)
df <- data.frame(Specialty = c("A", "B", "C"),
Recording_1 = c(100, 50, 60),
Recording_2 = c(200, -75, 100),
Recording_3 = c(300, 150, -25))
df %>%
pivot_longer(cols = !Specialty, names_to = "Recording",
values_to = "Value") %>%
ggplot(aes(x = Value, y = Specialty)) +
geom_point(aes(shape = Recording, color = Recording), size = 3)+
scale_y_discrete(limits = rev)+ #reverses A,B,C order
scale_x_continuous(labels = percent_format(scale = 1)) +
theme_classic()
Here is what the output looks like.
Related
You can copy the following code for the example which creates a barplot using ggplot2:
set.seed(999)
similarity_context_set1 = matrix(rnorm(10*3,10,1),ncol=3)
similarity_context_set2 = matrix(rnorm(10*3,10,1),ncol=3)
attraction_prop_context_set1 = matrix(rnorm(10*3,10,1),ncol=3)
attraction_prop_context_set2 = matrix(rnorm(10*3,10,1),ncol=3)
compromise_context_set1 = matrix(rnorm(10*3,10,1),ncol=3)
compromise_context_set2 = matrix(rnorm(10*3,10,1),ncol=3)
library(tidyverse)
library(ggthemes)
# add all matrices in a list. I use lst here since the ouptut is
# a named list
df <- data.frame(name1 = rep(rep(c("attraction", "compromise", "similarity"), each = 3), 2),
name2 = rep(c("1", "2"), each = 9),
x = rep(c("Third", "X", "Y"), 6),
y = rep(12, 18),
label = c("Now", "you", "can", "use", "any", "label", "you", "want",
"by", "inserting", "it", "as", "a", "string", "into", "this",
"character", "vector"))
lst(similarity_context_set1,
similarity_context_set2,
attraction_prop_context_set2,
attraction_prop_context_set1,
compromise_context_set1,
compromise_context_set2) %>%
# transform to tibble and add column names
map(as_tibble) %>%
map(set_names, c("X", "Y","Third")) %>%
# bind the list to one dataframe, add list names to column by
# setting .id
bind_rows(.id = "name") %>%
# transform data from wide to long as it is recommended ggplot
#input format here
pivot_longer(-1,names_to = "x", values_to = "y") %>%
# make to columns for facetting
separate(name, into = c("name1", "name2"), sep = "_", extra = "merge") %>%
mutate(name2 = str_extract(name2, "[0-9]")) %>%
# finally the plot
ggplot(aes(x, y, group=x, fill = x)) + theme_hc(base_size = 13)+
geom_bar(stat = "summary", fun = "mean",alpha=0.8 )+
scale_fill_manual(values = c("Y" = "gray1","X" = "gray1","Third" = "gray1"), guide="none" )+
facet_grid(name2~name1)+
stat_summary(fun.data = mean_se, geom = "errorbar", width=0.2)+
ggtitle("Perceptual Domain")+
theme(plot.title = element_text(hjust = 0.5))+
labs(x = "Response", y = "Mean Choice Proportion")+
geom_text(data = df, aes(label = label))
My question is how can I add different lines with labels? On the picture below you can see an example of what I mean:
Does anyone have an idea how I can do something like that?
This is much the same as your last question, and the answer much the same as the last answer. Please take time to read and understand what is happening in the code.
Create this data frame:
df2 <- data.frame(name1 = rep(c("attraction", "compromise", "similarity"), 2),
name2 = rep(c("1", "2"), each = 3),
yintercept = runif(6, 5, 10),
label = c("Now", "use", "whatever",
"label", "you", "like"))
And add this line:
geomtextpath::geom_texthline(data = df2, aes(yintercept = yintercept, label = label),
color = "red", size = 6, hjust = 0.8, vjust = -0.2, fontface = 2)
I have a data frame with: Fail [3,3,3,1] and Pass [50,40,50,10]
I just want to make a barplot of Fail and Pass
b_f <- barplot(dat_record$Fail[1], horiz = TRUE, ylab = "FAIL", las = 2, col = "red", xlim = c(0,200))
b_p <- barplot(dat_record$Pass[2], horiz = TRUE, ylab = "PASS", las = 2, col = "green", xlim = c(0,200))
How can i put this two barplots on top of eachother in one graphic/diagram, like this:
And second question:
How can i do this properly with ggplot2? I tried it out, but i always failed with:
ggplot(dat_failpass, aes = (x = fail, fill = "red")+
geom_bar(position = "dodge")+
coord_flip()
Can someone answer me this two question or can you give me any tipps? I'm new into this.
Thank you.
Since you want just the first value of the vectors "Fail" and "Pass" value, this code chunk must plot what you want:
library(ggplot2)
fail = c(3, 3, 3, 1)
pass = c(50, 40, 50, 10)
df = data.frame(value = c(fail[1], pass[1]), label = c('Fail', 'Pass'))
ggplot(df, aes(x = label, y = value)) +
geom_bar(stat = 'identity', position = 'stack') +
coord_flip() +
labs(y = 'Count') +
theme(axis.title.y = element_blank())
Here is the output:
Let us know if this solution solved your problem.
Using your data in this format, here the code for plot:
library(tidyverse)
#Data
df <- structure(list(Fail = c(3, 3, 3, 1), Pass = c(50, 40, 50, 10)), class = "data.frame", row.names = c(NA,
-4L))
Code:
#Reshape and plot
df %>% pivot_longer(cols = everything()) %>%
#Plot
ggplot(aes(x=name,y=value))+
geom_bar(stat = 'identity',fill='gray')+
coord_flip()+
theme_bw()
Output:
I want to build a bar chart showing comparison of cost in combination with two variables.
Data:
Cost should be in Y' axis and Age and Gender should be in X' axis.
To findout, which combination of Age and gender having more cost?
Can anyone help out on this ?
I tried:
x = c(q4$Age,q4$Gender)
y = q4$Cost
plt <- ggplot(data = q4, mapping = aes(x,y)) + geom_bar(stat = "identity")
I want help on to build Age and Gender bars should be in side by side to compare the cost of each combination of Age and Gender.
Thanks a lot for your valuable time.
You can have the use of interaction into your aes:
library(ggplot2)
ggplot(df, aes(x = interaction(age,gender), y = cost, fill = interaction(age, gender)))+
geom_bar(stat = "identity", position = position_dodge())
Alternatively, you can also create a new column in your dataframe (here using the function mutate from dplyr) and plot according to this column:
library(ggplot2)
library(dplyr)
df %>% mutate(Age_Gender = paste0("Age: ",age,"\n","Gender: ",gender)) %>%
ggplot(aes(x = Age_Gender, y = cost, fill = Age_Gender))+
geom_bar(stat = "identity", show.legend = FALSE)+
theme(axis.text.x = element_text(angle = 45, hjust =1))
Does it answer your question ?
Data
structure(list(age = c(1, 1, 2, 2, 3, 3, 4, 4, 5, 5), gender = structure(c(2L,
1L, 1L, 2L, 2L, 1L, 1L, 2L, 1L, 2L), .Label = c("F", "M"), class = "factor"),
cost = c(100, 45, 50, 56, 60, 55, 50, 70, 70, 60)), class = "data.frame", row.names = c(NA,
-10L))
It would be a lot easier with a sample of your data. Please, use dput and check here how to make a great R reproducible example.
However, as I read your request, you can use tidyverse
I wrote the following, please try this on your data inserting your relevant covariates
#Data
attatch(mtcars)
w <- mtcars
#Script
library(tidyverse)
w %>%
as_tibble() %>%
mutate(cyl=as.character(cyl),
vs =as.factor(vs)) %>%
bind_rows(., mutate(., cyl="all")) %>%
count(cyl, vs) %>%
ggplot(aes(cyl, n, color = vs, fill= vs)) +
scale_fill_manual(values = c("#fcebeb", "#edf1f9"), name="", label=c("Text 1", "Text 2")) +
scale_colour_manual(values = c("red", "#1C73C2"), name="", label=c("Text 1", "Text 2")) +
geom_col(position = position_dodge2(preserve = "single", padding = 0.1))
Which yields
datax$Gender <- as.factor(datax$Gender)
ggplot(datax, aes(fill=Gender, y=cost, x=Age)) + geom_bar(position="dodge",
stat="identity")
This is what is the output.I have a data set which contains unit, weight of each unit and compliance score for each unit in year 2016.
I was not able to add the table but here is the screenshot for the data in csv
I have named the columns in the data as unit, weight and year(which is compliance score) .
I want to create a sunburst chart where the first ring will be the unit divided based on weight and the second ring will be the same but will have labels compliance score.
The colour for each ring will be different.
I was able to do some code with the help from an online blog and the output I have gotten is similar to what I want but I am facing difficulty in positioning of the labels and also the colour coding for each ring
#using ggplot
library(ggplot2) # Visualisation
library(dplyr) # data wrangling
library(scales) # formatting
#read file
weight.eg = read.csv("Dummy Data.csv", header = FALSE, sep =
";",encoding = "UTF-8")
#change column names
colnames(weight.eg) <- c ("unit","weight","year")
#as weight column is factor change into integer
weight.eg$weight = as.numeric(levels(weight.eg$weight))
[as.integer(weight.eg$weight)]
weight.eg$year = as.numeric(levels(weight.eg$year))
[as.integer(weight.eg$year)]
#Nas are introduced, remove
weight.eg <- na.omit(weight.eg)
#Sum of the total weight
sum_total_weight = sum(weight.eg$weight)
#First layer
firstLevel = weight.eg %>% summarize(total_weight=sum(weight))
sunburst_0 = ggplot(firstLevel) # Just a foundation
#this will generate a bar chart
sunburst_1 =
sunburst_0 +
geom_bar(data=firstLevel, aes(x=1, y=total_weight),
fill='darkgrey', stat='identity') +
geom_text(aes(x=1, y=sum_total_weight/2, label=paste("Total
Weight", comma(total_weight))), color='black')
#View
sunburst_1
#this argument is used to rotate the plot around the y-axis which
the total weight
sunburst_1 + coord_polar(theta = "y")
sunburst_2=
sunburst_1 +
geom_bar(data=weight.eg,
aes(x=2, y=weight.eg$weight, fill=weight.eg$weight),
color='white', position='stack', stat='identity', size=0.6)
+
geom_text(data=weight.eg, aes(label=paste(weight.eg$unit,
weight.eg$weight), x=2, y=weight.eg$weight), position='stack')
sunburst_2 + coord_polar(theta = "y")
sunburst_3 =
sunburst_2 +
geom_bar(data=weight.eg,
aes(x=3, y=weight.eg$weight,fill=weight.eg$weight),
color='white', position='stack', stat='identity',
size=0.6)+
geom_text(data = weight.eg,
aes(label=paste(weight.eg$year),x=3,y=weight.eg$weight),position =
'stack')
sunburst_3 + coord_polar(theta = "y")
sunburst_3 + scale_y_continuous(labels=comma) +
scale_fill_continuous(low='white', high='darkred') +
coord_polar('y') + theme_minimal()
Output for dput(weight.eg)
structure(list(unit = structure(2:7, .Label = c("", "A", "B",
"C", "D", "E", "F", "Unit"), class = "factor"), weight = c(30,
25, 10, 17, 5, 13), year = c(70, 80, 50, 30, 60, 40)), .Names =
c("unit",
"weight", "year"), row.names = 2:7, class = "data.frame", na.action
= structure(c(1L,
8L), .Names = c("1", "8"), class = "omit"))
output for dput(firstLevel)
structure(list(total_weight = 100), .Names = "total_weight", row.names
= c(NA,
-1L), na.action = structure(c(1L, 8L), .Names = c("1", "8"), class =
"omit"), class = "data.frame")
So I think I might have some sort of solution for you. I wasn't sure what you wanted to color-code on the outer ring; from your code it seems you wanted it to be the weight again, but it was not obvious to me. For different colour scales per ring, you could use the ggnewscale package:
library(ggnewscale)
For the centering of the labels you could write a function:
cs_fun <- function(x){(cumsum(x) + c(0, cumsum(head(x , -1))))/ 2}
Now the plotting code could look something like this:
ggplot(weight.eg) +
# Note: geom_col is equivalent to geom_bar(stat = "identity")
geom_col(data = firstLevel,
aes(x = 1, y = total_weight)) +
geom_text(data = firstLevel,
aes(x = 1, y = total_weight / 2,
label = paste("Total Weight:", total_weight)),
colour = "black") +
geom_col(aes(x = 2,
y = weight, fill = weight),
colour = "white", size = 0.6) +
scale_fill_gradient(name = "Weight",
low = "white", high = "darkred") +
# Open up new fill scale for next ring
new_scale_fill() +
geom_text(aes(x = 2, y = cs_fun(weight),
label = paste(unit, weight))) +
geom_col(aes(x = 3, y = weight, fill = weight),
size = 0.6, colour = "white") +
scale_fill_gradient(name = "Another Weight?",
low = "forestgreen", high = "white") +
geom_text(aes(label = paste0(year), x = 3,
y = cs_fun(weight))) +
coord_polar(theta = "y")
Which looks like this:
I am trying to graph the following data:
to_graph <- structure(list(Teacher = c("BS", "BS", "FA"
), Level = structure(c(2L, 1L, 1L), .Label = c("BE", "AE", "ME",
"EE"), class = "factor"), Count = c(2L, 25L, 28L)), .Names = c("Teacher",
"Level", "Count"), row.names = c(NA, 3L), class = "data.frame")
and want to add labels in the middle of each piece of the bars that are the percentage for that piece. Based on this post, I came up with:
ggplot(data=to_graph, aes(x=Teacher, y=Count, fill=Level), ordered=TRUE) +
geom_bar(aes(fill = Level), position = 'fill') +
opts(axis.text.x=theme_text(angle=45)) +
scale_y_continuous("",formatter="percent") +
opts(title = "Score Distribution") +
scale_fill_manual(values = c("#FF0000", "#FFFF00","#00CC00", "#0000FF")) +
geom_text(aes(label = Count), size = 3, hjust = 0.5, vjust = 3, position = "stack")
But it
Doesn't have any effect on the graph
Probably doesn't display the percentage if it did (although I'm not entirely sure of this point)
Any help is greatly appreciated. Thanks!
The y-coordinate of the text is the actual count (2, 25 or 28), whereas the y-coordinates in the plot panel range from 0 to 1, so the text is being printed off the top.
Calculate the fraction of counts using ddply (or tapply or whatever).
graph_avgs <- ddply(
to_graph,
.(Teacher),
summarise,
Count.Fraction = Count / sum(Count)
)
to_graph <- cbind(to_graph, graph_avgs$Count.Fraction)
A simplified version of your plot. I haven't bothered to play about with factor orders so the numbers match up to the bars yet.
ggplot(to_graph, aes(Teacher), ordered = TRUE) +
geom_bar(aes(y = Count, fill = Level), position = 'fill') +
scale_fill_manual(values = c("#FF0000", "#FFFF00","#00CC00", "#0000FF")) +
geom_text(
aes(y = graph_avgs$Count.Fraction, label = graph_avgs$Count.Fraction),
size = 3
)