I have used a simple CSV table and made a plot with the desired colors and dots, but I cannot find the solution to connect the dots with a line.
#----Import data----#
DS <- read_csv("https://raw.githubusercontent.com/Iqbalpr/Tugas-Kuliah--UIN/main/Data%20Skripsi%20Gender%20%2B%20Negara%20(CSV).csv")
View(DS)
ncol(DS)
nrow(DS)
#----Check and convert column type----#
str(DS) # Check Column
DS$ID <- as.factor(DS$ID )
DS$Gender <- as.factor(DS$Gender)
DS$Tahun <- as.integer(DS$Tahun)
DS$Inflasi <- as.numeric(DS$Inflasi)
DS$Pengangguran <- as.numeric(DS$Pengangguran)
DS$`GDP growth rate` <- as.numeric(DS$`GDP growth rate`)
DS$`GDP per Capita` <- as.numeric(DS$`GDP per Capita`)
str(DS) # Check Column Again
#----Plot----#
p <- ggplot(DS) + aes(x = Tahun, y = AHH, group = Negara, color = Negara) + geom_point()
p
enter image description here
Now I want the dots connected with the same color as the dots and I use this code:
p <- ggplot(DS) + aes(x = Tahun, y = AHH, group = Negara, color = Negara) + geom_point() + geom_line()
p
but I get a very strange line like this :
enter image description here
What am I doing wrong?
This happens because you have two values per country because of your Gender column which will result in the graph you have. An option is to use facet_wrap to plot it for each Gender like this:
library(ggplot2)
p <- ggplot(DS) +
aes(x = Tahun, y = AHH, group = Negara, color = Negara) +
geom_point() +
geom_line() +
facet_wrap(~Gender)
p
Output:
Related
I have a csv file which looks like the following:
Name,Count1,Count2,Count3
application_name1,x1,x2,x3
application_name2,x4,x5,x6
The x variables represent numbers and the applications_name variables represent names of different applications.
Now I would like to make a barplot for each row by using ggplot2. The barplot should have the application_name as title. The x axis should show Count1, Count2, Count3 and the y axis should show the corresponding values (x1, x2, x3).
I would like to have a single barplot for each row, because I have to store the different plots in different files. So I guess I cannot use "melt".
I would like to have something like:
for each row in rows {
print barplot in file
}
Thanks for your help.
You can use melt to rearrange your data and then use either facet_wrap or facet_grid to get a separate plot for each application name
library(ggplot2)
library(reshape2)
# example data
mydf <- data.frame(name = paste0("name",1:4), replicate(5,rpois(4,30)))
names(mydf)[2:6] <- paste0("count",1:5)
# rearrange data
m <- melt(mydf)
# if you are wanting to export each plot separately
# I used facet_wrap as a quick way to add the application name as a plot title
for(i in levels(m$name)) {
p <- ggplot(subset(m, name==i), aes(variable, value, fill = variable)) +
facet_wrap(~ name) +
geom_bar(stat="identity", show_guide=FALSE)
ggsave(paste0("figure_",i,".pdf"), p)
}
# or all plots in one window
ggplot(m, aes(variable, value, fill = variable)) +
facet_wrap(~ name) +
geom_bar(stat="identity", show_guide=FALSE)
I didn't see #user20650's nice answer before preparing this. It's almost identical, except that I use plyr::d_ply to save things instead of a loop. I believe dplyr::do() is another good option (you'd group_by(Name) first).
yourData <- data.frame(Name = sample(letters, 10),
Count1 = rpois(10, 20),
Count2 = rpois(10, 10),
Count3 = rpois(10, 8))
library(reshape2)
yourMelt <- melt(yourData, id.vars = "Name")
library(ggplot2)
# Test a function on one piece to develope graph
ggplot(subset(yourMelt, Name == "a"), aes(x = variable, y = value)) +
geom_bar(stat = "identity") +
labs(title = subset(yourMelt, Name == 'a')$Name)
# Wrap it up, with saving to file
bp <- function(dat) {
myPlot <- ggplot(dat, aes(x = variable, y = value)) +
geom_bar(stat = "identity") +
labs(title = dat$Name)
ggsave(filname = paste0("path/to/save/", dat$Name, "_plot.pdf"),
myPlot)
}
library(plyr)
d_ply(yourMelt, .variables = "Name", .fun = bp)
Inserting this data:
df <- data.frame(year = c(2011,2012,2013,2014,2015,2016,2017,2018), value = c(337,423,551,661,846,1387,2222,3580))
How is it possible to produce a line plot like this using the df data?
enter image description here
Here is an example. Text placement relative to the points can be a bit finnicky.
library(ggplot2)
df <- data.frame(year = c(2011,2012,2013,2014,2015,2016,2017,2018),
value = c(337,423,551,661,846,1387,2222,3580))
ggplot(df, aes(year, value)) +
geom_point() +
geom_line() +
geom_text(aes(label = value, y = (value - 50)*0.9))
I am attempting to plot multiple time series variables on a single line chart using ggplot. I am using a data.frame which contains n time series variables, and a column of time periods. Essentially, I want to loop through the data.frame, and add exactly n goem_lines to a single chart.
Initially I tried using the following code, where;
df = data.frame containing n time series variables, and 1 column of time periods
wid = n (number of time series variables)
p <- ggplot() +
scale_color_manual(values=c(colours[1:wid]))
for (i in 1:wid) {
p <- p + geom_line(aes(x=df$Time, y=df[,i], color=var.lab[i]))
}
ggplotly(p)
However, this only produces a plot of the final time series variable in the data.frame. I then investigated further, and found that following sets of code produce completely different results:
p <- ggplot() +
scale_color_manual(values=c(colours[1:wid]))
i = 1
p = p + geom_line(aes(x=df$Time, y=df[,i], color=var.lab[i]))
i = 2
p = p + geom_line(aes(x=df$Time, y=df[,i], color=var.lab[i]))
i = 3
p = p + geom_line(aes(x=df$Time, y=df[,i], color=var.lab[i]))
ggplotly(p)
Plot produced by code above
p <- ggplot() +
scale_color_manual(values=c(colours[1:wid]))
p = p + geom_line(aes(x=df$Time, y=df[,1], color=var.lab[1]))
p = p + geom_line(aes(x=df$Time, y=df[,2], color=var.lab[2]))
p = p + geom_line(aes(x=df$Time, y=df[,3], color=var.lab[3]))
ggplotly(p)
Plot produced by code above
In my mind, these two sets of code are identical, so could anyone explain why they produce such different results?
I know this could probably be done quite easily using autoplot, but I am more interested in the behavior of these two snipits of code.
What you're trying to do is a 'hack' way by plotting multiple lines, but it's not ideal in ggplot terms. To do it successfully, I'd use aes_string. But it's a hack.
df <- data.frame(Time = 1:20,
Var1 = rnorm(20),
Var2 = rnorm(20, mean = 0.5),
Var3 = rnorm(20, mean = 0.8))
vars <- paste0("Var", 1:3)
col_vec <- RColorBrewer::brewer.pal(3, "Accent")
library(ggplot2)
p <- ggplot(df, aes(Time))
for (i in 1:length(vars)) {
p <- p + geom_line(aes_string(y = vars[i]), color = col_vec[i], lwd = 1)
}
p + labs(y = "value")
How to do it properly
To make this plot more properly, you need to pivot the data first, so that each aesthetic (aes) is mapped to a variable in your data frame. That means we need a single variable to be color in our data frame. Hence, we pivot_longer and plot again:
library(tidyr)
df_melt <- pivot_longer(df, cols = Var1:Var3, names_to = "var")
ggplot(df_melt, aes(Time, value, color = var)) +
geom_line(lwd = 1) +
scale_color_manual(values = col_vec)
If you run the code below you will a line graph. How can I change the color of the point at x = 2 to RED and increase it's size?
In this case the on the graph the point at (.6) where x = 2 would be highlighted red and made bigger.
Here is my code:
library("ggplot2")
data<-data.frame(time= c(1,2,3), value = c(.4,.6,.7))
ggplot(data, aes( x = time, y=value) ) + geom_line() + geom_point(shape = 7,size = 1)
Thank you!
If your dataset is small you could do this:
> library("ggplot2")
> data<-data.frame(time= c(1,2,3), value = c(.4,.6,.7),point_size=c(1,10,1),cols=c('black','red','black'))
> ggplot(data, aes( x = time, y=value) ) + geom_line() + geom_point(shape = 7,size = data$point_size, colour=data$cols)
Makes:
Also I would not advise calling your data frame data
In addition to #Harpal's solution, you can add two more columns to your data frame where pointsize and -color is specified according to particular conditions:
df <- data.frame(time= c(1,2,3), value = c(.4,.6,.7))
# specify condition and pointsize here
df$pointsize <- ifelse(df$value==0.6, 5, 1)
# specify condition and pointcolour here
df$pointcol <- ifelse(df$value==0.6, "red", "black")
ggplot(df, aes(x=time, y=value)) + geom_line() + geom_point(shape=7, size=df$pointsize, colour=df$pointcol)
You may change ifelse(df$value==0.6, 5, 1) to meet any criteria you like, or you use a more complex approach to specifiy more conditions to be met:
df <- data.frame(time= c(1,2,3), value = c(.4,.6,.7))
df$pointsize[which(df$value<0.6)] <- 1
df$pointsize[which(df$value>0.6)] <- 8
df$pointsize[which(df$value==0.6)] <- 5
df$pointcol[which(df$value<0.6)] <- "black"
df$pointcol[which(df$value>0.6)] <- "green"
df$pointcol[which(df$value==0.6)] <- "red"
ggplot(df, aes(x=time, y=value)) + geom_line() + geom_point(shape=7, size=df$pointsize, colour=df$pointcol)
I have two graphs with the same x axis - the range of x is 0-5 in both of them.
I would like to combine both of them to one graph and I didn't find a previous example.
Here is what I got:
c <- ggplot(survey, aes(often_post,often_privacy)) + stat_smooth(method="loess")
c <- ggplot(survey, aes(frequent_read,often_privacy)) + stat_smooth(method="loess")
How can I combine them?
The y axis is "often privacy" and in each graph the x axis is "often post" or "frequent read".
I thought I can combine them easily (somehow) because the range is 0-5 in both of them.
Many thanks!
Example code for Ben's solution.
#Sample data
survey <- data.frame(
often_post = runif(10, 0, 5),
frequent_read = 5 * rbeta(10, 1, 1),
often_privacy = sample(10, replace = TRUE)
)
#Reshape the data frame
survey2 <- melt(survey, measure.vars = c("often_post", "frequent_read"))
#Plot using colour as an aesthetic to distinguish lines
(p <- ggplot(survey2, aes(value, often_privacy, colour = variable)) +
geom_point() +
geom_smooth()
)
You can use + to combine other plots on the same ggplot object. For example, to plot points and smoothed lines for both pairs of columns:
ggplot(survey, aes(often_post,often_privacy)) +
geom_point() +
geom_smooth() +
geom_point(aes(frequent_read,often_privacy)) +
geom_smooth(aes(frequent_read,often_privacy))
Try this:
df <- data.frame(x=x_var, y=y1_var, type='y1')
df <- rbind(df, data.frame(x=x_var, y=y2_var, type='y2'))
ggplot(df, aes(x, y, group=type, col=type)) + geom_line()