ggplot2 with factor variable y axis and removed whitespace - r

I have a plot like the one below, with a factor variable on the y-axis.
library(reshape2)
library(ggplot2)
MA <- c("A", "B", "C")
dfr <- data.frame(
name = factor(MA, levels = MA),
start = 1:3,
end = 3:5,
prozent = c(1,0.5,0.75)
)
mdfr <- melt(dfr, measure.vars = c("start", "end"))
ggplot(mdfr, aes(value, name)) + geom_line(aes(size = prozent)) + scale_size_area()
I want to remove the whitespace (or, in default ggplot2, "greyspace") between the horizontal lines so that they touch each other.

You could do as follows:
ggplot(mdfr, aes(value, name)) +
geom_line(aes(size = prozent)) +
scale_size_area() +
scale_y_discrete(expand = c(7, 0))

Related

How to set specific colors lines in ggplot2?

I am trying to plot multiple lines using ggplot2. Below, there is an example of code.
I would like to plot the variables (class) 1 to 3 with grey color and mean with red color.
library('reshape2')
library('ggplot2')
times <- seq(100, 1000, by=100)
values <- data.frame(runif(10), runif(10), runif(10))
mean <- rowMeans(values)
df <- data.frame(times, values, mean)
names(df)=c("time", 1:3, 'means')
melted = melt(df, id.vars = "time", value.name="values",
variable.name="class")
plot <- ggplot(data=melted, aes(x=time, y=values, group = class)) + geom_line() + labs(y= "Values", x = "Time")
ggplot(
data=melted,
aes(x=time, y=values, color = class == "means", group = class)
) +
geom_line() +
labs(y= "Values", x = "Time") +
scale_color_manual(values = c("grey", "red"))

Draw only specific axis text labels

I have the following data.table:
require(data.table)
require(ggplot2)
set.seed(1234)
dt = data.table(id = paste0('ID_', 1:2000),
group = rep(LETTERS[1:5], 400),
value = as.logical(rbinom(2000, 1, prob = 0.25)))
I would like to create a ggplot like below, where on the y-axis only the text labels, for which the variable value equals TRUE are drawn, without removing the other data. Additionally, it would be best, if the text labels won't overlap (if possible), hence using all the empty y-axis space.
# draws all categorical id values
ggplot(dt, aes(y = reorder(id, -value), x = group, fill = value)) +
geom_tile() +
theme_bw()
Update: For the first 100 cases:
dt1 <- dt %>%
mutate(ylabel = ifelse(value==TRUE, id, "")) %>%
slice(1:100)
ggplot(dt1, aes(y = reorder(id, -value), x = group, fill = value)) +
geom_tile() +
scale_y_discrete(
labels = dt1$ylabel
) +
theme_bw()

draw stack chart in r

I want to draw a stack chart in R :
My data set is as follows called df:
df <- structure(list(id = c("A","B"),
x1 = c(10,30),
x2 = c(20,40),
x3 = c(70,30)), row.names = 1:2,
class = "data.frame")
df<- melt(df, id.vars = "id")
library(ggplot2)
ggplot(data = df, aes(x = variable, y = value, fill =id)) +
geom_bar(stat = "identity") +
xlab("\nCategory") +
ylab("Percentage\n") +
guides(fill = FALSE) +
theme_bw()
The out put is not the one that I want,
I want to to see id in the x axis and x1,x2,x3 in the stacked column.
ggplot's x always specifies the x-axis, fill the variable you want to categorize your data by. So to create your desired plot, the code is:
library(reshape2) ## for melt()
library(ggplot2)
df<- melt(n_df, id.vars = "id")
ggplot(data = n_df, aes(x = id, y = value, fill =variable)) +
geom_bar(stat = "identity") +
xlab("\nCategory") +
ylab("Percentage\n") +
guides(fill = FALSE) +
theme_bw()
If you want to have the legend show up, you have to guides(fill = TRUE) :

Change order of x label in facet plot using ggplot

I'm trying to plot the facet plot below in alphabetical order, I've tried multiple ways of doing it and even tried getting rid of the facet and just plotting Overpaid vs proportion, but the plot still had an alphabetical x axis.
Initially I tried assigning a frequency value to every element then ordering the list by that value but that didn't change the plot.
overpaid_each_country <- survey_df %>%
filter(!is.na(Overpaid)) %>%
filter(Country %in% Country_Sum$Var1)
overpaid_each_country <- overpaid_each_country[ , which(names(overpaid_each_country) %in% c("Overpaid","Country"))]
overpaid_each_country <- transform(overpaid_each_country, freq = ave(seq(nrow(overpaid_each_country)), Overpaid, FUN=length))
overpaid_each_country <- overpaid_each_country[order(overpaid_each_country$freq), ]
Then I tried setting the factor levels but although the factor levels changed, the plot didn't.
overpaid_each_country %>%
mutate(Overpaid2 = factor(Overpaid, levels = c("Greatly overpaid", "Somewhat overpaid", "Greatly underpaid", "Neither underpaid nor overpaid", "Somewhat underpaid"))) %>%
ggplot(aes(x = Overpaid2, y = ..prop.., group = 1)) +
geom_bar( color = "white", fill = "#42dff4") +
facet_wrap(~ Country, nrow = 4) +
aes(stringr::str_wrap(Overpaid, 10)) +
xlab("OverPaid orUnderpaid") +
ylab("Proportion of Respondents")+
labs(title = "Are you Overpaid or Underpaid?") +
theme(axis.title.x=element_blank(), axis.text.y=element_text(size=12), axis.text.x = element_text(size=12), plot.title = element_text(size = 17))
You could use forcats::fct_reorder() to re-order your factor-levels, or you change the levels from somethink like "a" to "e", and then pass a named vector (where names match factor levels) to scale_x_discrete() as labels-argument.
library(ggplot2)
d <- data.frame(
x = factor(sample(1:5, size = 100, replace = TRUE), labels = c("a", "b", "c", "d", "e"))
)
ggplot(d, aes(x = x, y = ..prop..)) + geom_bar()
labels <- c(a = "Greatly underpaid", b = "Somewhat underpaid", c = "Neither/nor", d = "somewhat overpaid", e = "greatly overpaid")
ggplot(d, aes(x = x, y = ..prop..)) +
geom_bar() +
scale_x_discrete(labels = labels)
In your 6th line
aes(stringr::str_wrap(Overpaid, 10)) +
change to overpaid2
aes(stringr::str_wrap(Overpaid2, 10)) +

create two separate ggplots with comparable y axis but with different y limits

I am trying to plot bar graphs on a map following this example: How to plot barchart onto ggplot2 map. This works fine but in contrast to the example I would like to add x and y axis. The problem is that the y range of the data differs considerably across the regions for which I would like to create the bar graphs.
In order to produce comparable graphs (i.e. where the y axis has an identical dimension), I apply the same y limits to all graphs and adjust the breaks for each graph. This is, however, not a good solution as some of the graphs (p2 in this case) have a large empty area above and below the bars. In order to make it work, I am looking for a method top crop the graphs to remove the empty areas, while at the same time maintaining the dimensions of the graph so that y axis can be compared.
library(dplyr)
library(ggplot2)
df <- data.frame(type = c("A", "B", "A", "B"), country = c("NLD", "NLD", "BEL", "BEL"), value = c(10, -10, 5, 2))
df1 <- filter(df, country == "NLD")
p1 <- ggplot(data = df1) +
geom_col(aes(x = type, y = value)) +
scale_y_continuous(limits = c(min(df$value), max(df$value)), breaks = seq(min(df1$value), max(df1$value), 2)) +
theme_bw()
p1
df2 <- filter(df, country == "BEL")
p2 <- ggplot(data = df2) +
geom_col(aes(x = type, y = value)) +
scale_y_continuous(limits = c(min(df$value), max(df$value)), breaks = seq(min(df2$value), max(df2$value), 2)) +
theme_bw()
p2
Have you tried coord_fixed for each of the plot? If you can control the width of each plot the same, the height of bars will be comparable.
library(dplyr)
library(ggplot2)
library(gridExtra)
df <- data.frame(type = c("A", "B", "A", "B"), country = c("NLD", "NLD", "BEL", "BEL"), value = c(10, -10, 5, 2))
df1 <- filter(df, country == "NLD")
p1 <- ggplot(data = df1) +
geom_col(aes(x = type, y = value)) +
# scale_y_continuous(limits = c(min(df$value), max(df$value)), breaks = seq(min(df1$value), max(df1$value), 2)) +
theme_bw()
df2 <- filter(df, country == "BEL")
p2 <- ggplot(data = df2) +
geom_col(aes(x = type, y = value)) +
# scale_y_continuous(limits = c(min(df$value), max(df$value)), breaks = seq(min(df2$value), max(df2$value), 2)) +
theme_bw()
x_range <- length(unique(df$type))
y_range1 <- max(df1$value) - min(df1$value)
y_range2 <- max(df2$value) - min(df2$value)
g1 <- p1 + coord_fixed(ratio = x_range / y_range1)
g2 <- p2 + coord_fixed(ratio = x_range / y_range1)
# example output
grid.arrange(g1, g2, nrow = 1)

Resources