single level variable in ggplot2::geom_tile - r

I've got a data frame with three variables, location, price, and varname.
I'd like to use ggplot2's geom_tile to make a heat map of sorts. This plot almost looks like a bar chart, but I prefer geom_tile because I like the values, big or small, to be allocated the same amount of physical space on the plot. My code almost gets me there.
The first problem's that I can't format the plot so to get rid of all the white space to the left and right of my pseudo-bar. The second problem's that I can't remove the Price legend below the plot, because I'd like Price only to feature in the legend above the plot.
Thanks for any help!
Starting point (df):
df <- data.frame(location=c("AZ","MO","ID","MI"),price=c(1380.45677,1745.1245,12.45652,1630.65341),varname=c("price","price","price","price"))
Current code:
library(ggplot2)
ggplot(df, aes(varname,location, width=.2)) + geom_tile(aes(fill = price),colour = "white") + geom_text(aes(label = round(price, 3))) +
scale_fill_gradient(low = "ivory1", high = "green") +
theme_classic() + labs(x = "", y = "") + theme(legend.position = "none") + ggtitle("Price")

Don't set the width to 0.2.
Use theme to disable the labels and ticks.
You might want to use coord_equal to get nice proportions (i.e. squares). expand = FALSE gets rid of all white space.
.
ggplot(df, aes(varname, location)) +
geom_tile(aes(fill = price), colour = "white") +
geom_text(aes(label = round(price, 3))) +
scale_fill_gradient(low = "ivory1", high = "green") +
theme_classic() + labs(x = "", y = "") +
theme(legend.position = "none", axis.text.x = element_blank(), axis.ticks.x = element_blank()) +
ggtitle("Price") +
coord_equal(expand = FALSE)

Related

Ggplot2 fill by one condition, but shade by another

I am having trouble with ggplot2. I am trying to plot this boxplot that has several boxes for every x-axis value. Each set of boxplots is divided into two sets, features, and resolutions, with every feature set having boxes for every resolution. My issue is that I want to color(and fill) by feature set, but have different shades of that color for every resolution. I have only been able to color by feature and fill by resolution so far, and this is my code:
df %>%
ggplot( aes(x=partition, y=value, fill=resolution,color=feature_set)) +
scale_color_manual(values = c('black','blue3','darkred')) +
geom_boxplot(aes(color=feature_set,fill=resolution),lwd=0.7) +
scale_fill_brewer(palette = "Pastel1") +
theme(
legend.position="right",
plot.title = element_text(size=11)
) +
theme_bw() +
geom_text(data = df,aes(y=1.1,label=max_clusters,color=feature_set),size = 2.5,
position = position_dodge(width = 0.85),check_overlap = TRUE) +
xlab('label') +
ylab('label') +
ggtitle("title") +
ylim(0,1.1)
Thank you so much in advance.

Set color of the boxes in a boxplot

hist <- ggplot(df, aes(x = A,fill = ("red"))) +
geom_bar() +
theme_minimal() +
ggtitle("Treatment") + theme(legend.position = "bottom", plot.title = element_text(hjust=0.5), text = element_text(size = 20)) +
scale_fill_manual("A", values = c("0" = "dodgerblue4", "1" = "chocolate"))
hist
I need help regarding setting the colors of the boxplots from the ggplot2 package which I am learning right now. I want the left one to be in the blue color and the right one in the other color. But unfortunately I cannot figure out how to set these instead this code just sets the right colors in the Legend and leaves the boxes unchanged?!
Like Rene said it is a bit hard to help while not seeing the dataset.
Looking at the given code your A contains two values you want to color individually
define a vector containing those two values:
df_colors <- c("0" , "1")
hist <- ggplot(df, aes(x = A, fill = df_colors )) +
geom_bar() +
theme_minimal() +
ggtitle("Treatment") + theme(legend.position = "bottom", plot.title = element_text(hjust=0.5), text = element_text(size = 20)) +
scale_fill_manual("A", values = c("0" = "dodgerblue4", "1" = "chocolate"))
Not enough code for me to know exactly what you're doing but I think if you remove:
mapping = aes(fill = "red")
it will solve your problem. A reprex would help others better understand your problem. I think instead you might need something like:
ggplot(data = your_data) +
geom_bar(mapping = aes(x = variable_1, y = variable_2, fill = variable_3), position = "dodge")

bar plot with named groups on x-axis in ggplot2?

it want to make a plot of this type in ggplot, but cant get it to work (made in excel):
So that there are cities on the x-axis, but they are arranged according to which state they are in.
The color of each bar is based on some third property, for example size of city (large, small or medium), and the y-axis is a measurement of whatever! A legend of (large, small, medium) should be included, just isn't in the figure I pasted here.
Example data:
state <- c(rep("Texas",3),rep("Colorado",3),rep("Nevada",3))
city <- c("Houston","Austin","Dallas","Denver","Boulder","Aspen","Reno","Sparks","Henderson")
size <- c(rep(c("large","medium","small"),3))
value <- runif(9, 10,50)
df <- data.frame(state,city,size, value)
So far, I have done this:
plot <- ggplot(df, aes(x=State, y=value)) +
geom_bar(aes(fill=size),position = "dodge", stat = "identity", color="black")
plot
But then each bar is not labeled with the city name.
Any ideas?
Answer
(Credit to https://dmitrijskass.netlify.app/2019/06/30/multi-level-labels-with-ggplot2/ )
Use facet_grid:
ggplot(df, aes(x=city, y = value)) +
geom_col() +
facet_grid(~ state,
scales = "free_x",
space = "free_x",
switch = "x")
More complete version
ggplot(df, aes(x=city, y = value)) +
geom_col() +
facet_grid(~ state,
scales = "free_x",
space = "free_x",
switch = "x") +
theme(panel.spacing = unit(0, units = "cm"), # removes space between panels
strip.placement = "outside", # moves the states down
strip.background = element_rect(fill = "white") # removes the background from the state names

How to stack filled areas instead of overlapping them using ggplot?

I have a Lorenz Curve graph that I filled by factor variables (male and female). This was done simply enough and overlapping was not an issue because there were only two factors.
Wage %>%
ggplot(aes(x = salary, fill = gender)) +
stat_lorenz(geom = "polygon", alpha = 0.65) +
geom_abline(linetype = "dashed") +
coord_fixed() +
scale_fill_hue() +
theme(legend.title = element_blank()) +
labs(x = "Cumulative Percentage of Observations",
y = "Cumulative Percentage of Wages",
title = "Lorenz curve by sex")
This provides the following graph:
However, when I have more than two factors (in this case four), the overlapping becomes a serious problem even if I use contrasting colors. Changing alpha does not do much at this stage. Have a look:
Wage %>%
ggplot(aes(x = salary, fill = Diploma)) +
stat_lorenz(geom = "polygon", alpha = 0.8) +
geom_abline(linetype = "dashed") +
coord_fixed() +
scale_fill_manual(values = c("green", "blue", "black", "white")) +
theme(legend.title = element_blank()) +
labs(x = "Cumulative Percentage of Observations",
y = "Cumulative Percentage of Wages",
title = "Lorenz curve by diploma")
At this point I've tried all different color pallettes, hues, brewers, manuals etc. I've also tried reordering the factors but as you can imagine, this did not work as well.
What I need is probably a single argument or function to stack all these areas on top of each other so they all have their distinct colors. Funny enough, I've failed to find what I'm looking for and decided to ask for help.
Thanks a lot.
The problem was solved by a dear friend. This was done by adding the categorical variables layer by layer, without defining the Lorenz Curve as a whole.
ggplot() + scale_fill_manual(values = wes_palette("GrandBudapest2", n = 4)) +
stat_lorenz(aes(x=Wage[Wage$Diploma==levels(Wage$Diploma)[3],]$salary, fill=Wage[Wage$Diploma==levels(Wage$Diploma)[3],]$Diploma), geom = "polygon") +
stat_lorenz(aes(x=Wage[Wage$Diploma==levels(Wage$Diploma)[4],]$salary, fill=Wage[Wage$Diploma==levels(Wage$Diploma)[4],]$Diploma), geom = "polygon") +
stat_lorenz(aes(x=Wage[Wage$Diploma==levels(Wage$Diploma)[2],]$salary, fill=Wage[Wage$Diploma==levels(Wage$Diploma)[2],]$Diploma), geom = "polygon") +
stat_lorenz(aes(x=Wage[Wage$Diploma==levels(Wage$Diploma)[1],]$salary, fill=Wage[Wage$Diploma==levels(Wage$Diploma)[1],]$Diploma), geom = "polygon") +
geom_abline(linetype = "dashed") +
coord_fixed() +
theme(legend.title = element_blank()) +
labs(x = "Cumulative Percentage of Observations",
y = "Cumulative Percentage of Wages",
title = "Lorenz curve by diploma")
Which yields:

Manually change order of y axis items on complicated stacked bar chart in ggplot2

I've been stuck on an issue and can't find a solution. I've tried many suggestions on Stack Overflow and elsewhere about manually ordering a stacked bar chart, since that should be a pretty simple fix, but those suggestions don't work with the huge complicated mess of code I plucked from many places. My only issue is y-axis item ordering.
I'm making a series of stacked bar charts, and ggplot2 changes the ordering of the items on the y-axis depending on which dataframe I am trying to plot. I'm trying to make 39 of these plots and want them to all have the same ordering. I think ggplot2 only wants to plot them in ascending order of their numeric mean or something, but I'd like all of the bar charts to first display the group "Bird Advocates" and then "Cat Advocates." (This is also the order they appear in my data frame, but that ordering is lost at the coord_flip() point in plotting.)
I think that taking the data frame through so many changes is why I can't just add something simple at the end or use the reorder() function. Adding things into aes() also doesn't work, since the stacked bar chart I'm creating seems to depend on those items being exactly a certain way.
Here's one of my data frames where ggplot2 is ordering my y-axis items incorrectly, plotting "Cat Advocates" before "Bird Advocates":
Group,Strongly Opposed,Opposed,Slightly Opposed,Neutral,Slightly Support,Support,Strongly Support
Bird Advocates,0.005473026,0.010946052,0.012509773,0.058639562,0.071149335,0.31118061,0.530101642
Cat Advocates,0.04491726,0.07013396,0.03624901,0.23719464,0.09141056,0.23404255,0.28605201
And here's all the code that takes that and turns it into a plot:
library(ggplot2)
library(reshape2)
library(plotly)
#Importing data from a .csv file
data <- read.csv("data.csv", header=TRUE)
data$s.Strongly.Opposed <- 0-data$Strongly.Opposed-data$Opposed-data$Slightly.Opposed-.5*data$Neutral
data$s.Opposed <- 0-data$Opposed-data$Slightly.Opposed-.5*data$Neutral
data$s.Slightly.Opposed <- 0-data$Slightly.Opposed-.5*data$Neutral
data$s.Neutral <- 0-.5*data$Neutral
data$s.Slightly.Support <- 0+.5*data$Neutral
data$s.Support <- 0+data$Slightly.Support+.5*data$Neutral
data$s.Strongly.Support <- 0+data$Support+data$Slightly.Support+.5*data$Neutral
#to percents
data[,2:15]<-data[,2:15]*100
#melting
mdfr <- melt(data, id=c("Group"))
mdfr<-cbind(mdfr[1:14,],mdfr[15:28,3])
colnames(mdfr)<-c("Group","variable","value","start")
#remove dot in level names
mylevels<-c("Strongly Opposed","Opposed","Slightly Opposed","Neutral","Slightly Support","Support","Strongly Support")
mdfr$variable<-droplevels(mdfr$variable)
levels(mdfr$variable)<-mylevels
pal<-c("#bd7523", "#e9aa61", "#f6d1a7", "#999999", "#c8cbc0", "#65806d", "#334e3b")
ggplot(data=mdfr) +
geom_segment(aes(x = Group, y = start, xend = Group, yend = start+value, colour = variable,
text=paste("Group: ",Group,"<br>Percent: ",value,"%")), size = 5) +
geom_hline(yintercept = 0, color =c("#646464")) +
coord_flip() +
theme(legend.position="top") +
theme(legend.key.width=unit(0.5,"cm")) +
guides(col = guide_legend(ncol = 12)) + #has 7 real columns, using to adjust legend position
scale_color_manual("Response", labels = mylevels, values = pal, guide="legend") +
theme(legend.title = element_blank()) +
theme(axis.title.x = element_blank()) +
theme(axis.title.y = element_blank()) +
theme(axis.ticks = element_blank()) +
theme(axis.text.x = element_blank()) +
theme(legend.key = element_rect(fill = "white")) +
scale_y_continuous(breaks=seq(-100,100,100), limits=c(-100,100)) +
theme(panel.background = element_rect(fill = "#ffffff"),
panel.grid.major = element_line(colour = "#CBCBCB"))
The plot:
I think this works, you may need to play around with the axis limits/breaks:
library(dplyr)
mdfr <- mdfr %>%
mutate(group_n = as.integer(case_when(Group == "Bird Advocates" ~ 2,
Group == "Cat Advocates" ~ 1)))
ggplot(data=mdfr) +
geom_segment(aes(x = group_n, y = start, xend = group_n, yend = start + value, colour = variable,
text=paste("Group: ",Group,"<br>Percent: ",value,"%")), size = 5) +
scale_x_continuous(limits = c(0,3), breaks = c(1, 2), labels = c("Cat", "Bird")) +
geom_hline(yintercept = 0, color =c("#646464")) +
theme(legend.position="top") +
theme(legend.key.width=unit(0.5,"cm")) +
coord_flip() +
guides(col = guide_legend(ncol = 12)) + #has 7 real columns, using to adjust legend position
scale_color_manual("Response", labels = mylevels, values = pal, guide="legend") +
theme(legend.title = element_blank()) +
theme(axis.title.x = element_blank()) +
theme(axis.title.y = element_blank()) +
theme(axis.ticks = element_blank()) +
theme(axis.text.x = element_blank()) +
theme(legend.key = element_rect(fill = "white"))+
scale_y_continuous(breaks=seq(-100,100,100), limits=c(-100,100)) +
theme(panel.background = element_rect(fill = "#ffffff"),
panel.grid.major = element_line(colour = "#CBCBCB"))
produces this plot:
You want to factor the 'Group' variable in the order by which you want the bars to appear.
mdfr$Group <- factor(mdfr$Group, levels = c("Bird Advocates", "Cat Advocates")

Resources