how do I use geom_rect with discrete axis values
You can try:
ggplot(data = df) +
geom_rect(data = df, aes(x = x, y=y), xmin = as.numeric(df$x[[2]]) - 0.3,
xmax = as.numeric(df$x[[3]]) + 0.3,
ymin = 0, ymax = 2)
This works, as if you call xmin and xmax etc outside of the aes
call, you can use whatever you want. The factor levels are used in the plot to plot them out, so as.numeric
will make sure you get the right one.
Widen geom_rect()-rectangle in ggplot2 on discrete scale
Just set xmin
and xmax
to -Inf
and Inf
respectively.
exp %>%
ggplot(aes(b,a)) +
geom_rect(aes(xmin=-Inf,xmax=Inf,ymin=0,ymax=50,fill="red"))+
geom_point()
plotting rectangles and lineranges with discrete axis in ggplot2
You can also use geom_tile
in place of geom_rect
:
ggplot(mydat, aes(est, mylvl)) +
geom_tile(aes(width = ciup-cilow, height=0.1), fill="red", color="black") +
geom_point() +
facet_grid(mytrt ~ mymsmt, scales = "free")
ggplot2 geom_rect plot quartiles stacked with data point and discrete x-axis
Here are two possible approaches, depending on your needs. In either case, though, I think geom_col
would be easier. (It's possible to use geom_rect
when your x-axis data is discrete, but it's not the most straightforward. Example)
Sample data (I switched Q3 & Q4 values for Lab as Q3's value was larger, which didn't make sense):
msr_type <- c('Clinic','Hospital','Lab','Office')
result <- c(10.5, 21.9, 30.5, 14.5)
sec_q <- c(9.5, 15.2, 25, 9)
third_q <- c(11, 17, 29, 20)
four_q <- c(17, 25, 34, 25)
df_check <- data.frame(msr_type, result, sec_q, third_q, four_q)
Approach 1 (keeping the wide format of the original dataset):
ggplot(df_check,
aes(x = msr_type)) +
geom_col(aes(y = four_q), fill = "slategray3") +
geom_col(aes(y = third_q), fill = "slategray2") +
geom_col(aes(y = sec_q), fill = "slategray1") +
geom_point(aes(y = result)) +
xlab("") + ylab("")
Since Q2 <= Q3 <= Q4, you can simply create one set of bars for each quartile & overlay them. But if you need a legend for Q2 / Q3 / Q4, it's not that straightforward...
Approach 2 (converting the dataset to long format so that all the quartile values are in the same variable):
df_check2 <- df_check %>%
tidyr::gather(quartile, quartile.value, -msr_type, -result) %>%
mutate(quartile = factor(quartile, levels = c("sec_q", "third_q", "four_q")))
ggplot(df_check2,
aes(x = msr_type)) +
geom_col(aes(y = quartile.value, fill = quartile),
position = position_dodge(0), width = 2.5) +
geom_point(aes(y = result)) +
scale_fill_manual(values = c("slategray1", "slategray2", "slategray3")) +
xlab("") + ylab("")
A legend is created by default using this approach. It's also more flexible if you have other quartiles / deciles / percentiles / etc to plot.
ymin and ymax for discrete axis in geom_area
Like Joran says, just put the geom_area
data outside of aes
. Logical because you aren't mapping.
m <- median(esoph$ncases)
Q1 <- quantile(as.numeric(esoph$ncases), c(0.25))
Q3 <- quantile(as.numeric(esoph$ncases), c(0.75))
ggplot(esoph, aes(x=agegp, y=ncases))+
geom_rect(xmin = -Inf , xmax = Inf , ymin = Q1 , ymax = Q3 ,fill = "blue", alpha = .002)+
geom_hline(yintercept= m,colour = "white", size=1) + geom_boxplot(aes(group=agegp))+ coord_flip() + geom_point() +
theme_classic()
How to get a ggplot2 function of discrete geom_rect to obey the alpha (transparency) values
I don't see a scale_alpha_identity
or scale_alpha_continuous(range = c(0, 0.2))
, so I suspect ggplot
is mapping your various alpha values to the default range of (0.1, 1)
, regardless of the range of the underlying values.
Here's a short example:
library(tidyverse); library(lubridate)
my_data <- tibble(
date = seq.Date(ymd(20190101), ymd(20191231), by = "5 day"),
month = month(date),
color = case_when(month <= 2 ~ "cornflowerblue",
month <= 5 ~ "springgreen4",
month <= 8 ~ "goldenrod2",
month <= 11 ~ "orangered3",
TRUE ~ "cornflowerblue"))
my_data %>%
uncount(20, .id = "row") %>%
mutate(alpha_val = row / max(row) * 0.2) %>%
ggplot(aes(date, 5 + alpha_val * 5, fill = color, alpha = alpha_val)) +
geom_tile(color = NA) +
scale_fill_identity() +
scale_alpha_identity() +
expand_limits(y = 0) +
coord_polar() +
theme_void()
Using factor levels with geom_rect
I got some help after asking the same question on the comp.lang.r.general mailing list
(http://permalink.gmane.org/gmane.comp.lang.r.general/313656). I ended up adding the following:
nodelist <- sort(levels(flatdata$value))
and then using
geom_rect(aes(ymin=as.Date("8-Apr-2014", format="%d-%b-%Y"),
ymax=as.Date("30-Apr-2014", format="%d-%b-%Y"),
xmin=which(nodelist=="node004")-0.5,
xmax=which(nodelist=="node004")+0.5,
fill="red", alpha=0.25))
colour geom_rect under certain condition
OP, this should probably help you. You're trying to draw what appears to be a column or bar chart. In this case, it's probably best to use geom_col
instead of geom_rect
. With geom_col
you only have to supply an x
aesthetic (discrete value), and a y
aesthetic for the height of the bar. You have not shared your data, but it seems the x axis is categorical already in your dataset, right?
Here's a reprex:
library(ggplot2)
set.seed(1234)
df <- data.frame(x=LETTERS, y=rnorm(26))
ggplot(df, aes(x,y)) +
geom_col(
aes(fill=ifelse(y>0, 'positive', 'negative')),
color='black', alpha=0.8
) +
scale_fill_manual(name='Value', values=c('positive'='orange', 'negative'='gray'))
What's going on here is that we only have to supply x
and y
to get the bars in the correct place and set the height. For the fill
of each of the bars, you can actually just set the label to be "positive" or "negative" (or whatever your desired label would be) on the fly via an ifelse
statement. Doing this alone will result in creating a legend automatically with fill colors chosen automatically. To fix a particular set of colors, I'm setting that manually via scale_fill_manual()
and supplying a named vector to the values
argument.
In your case, you can probably do something similar for geom_rect
. That is, you could just try specifying fill=
inside aes()
and following a similar manner to here if you want... but I'd recommend switching to use geom_col
, as it is most appropriate for what you're doing.
EDIT
As OP indicated in the comment, in the original question on which this is based, geom_rect
is required since the bars minimum is not always the same number. The ymin
aesthetic changes, so it makes sense to use geom_rect
here.
The brute force way is to still use ifelse
statements inside aes()
for fill
. It get's a bit dodgey, but it gets the job done:
ggplot(df) +
geom_rect(
aes(
xmin = char2num(sites) - 0.4,
xmax = char2num(sites) + 0.4,
ymin = ifelse(trop == "pt", 0.1, 1),
ymax = conc,
fill = ifelse(trop == "pt",
ifelse(conc > 0.1, 'positive', 'negative'),
ifelse(conc > 1, 'positive', 'negative'))
),
colour = 'black', alpha = 0.8
) +
scale_y_log10() +
# Fake discrete axis
scale_x_continuous(labels = sort(unique(df$sites)),
breaks = 1:3) +
scale_fill_manual(name='Conc', values=c('positive'='orange', 'negative'='gray')) +
facet_grid(. ~ trop) +
theme_bw()
To complete the setup, you may want to adjust the order of the items in the legend and avoid some of that kind of icky nested ifelse
stuff. In that case, you can always do the checking outside the ggplot
call. If you have more than the two values for df$trop
, you can consider creating the df$conc_min
column via a merge with another dataset, but it works just fine here.
df$conc_adjust <- char2num(df$sites)
df$conc_min <- ifelse(df$trop=='pt', 0.1, 1)
df$status <- ifelse(df$conc > df$conc_min, 'positive', 'negative')
# levels of the factor = the order appearing in the legend
df$status <- factor(df$status, levels=c('positive', 'negative'))
ggplot(df) +
geom_rect(
aes(
xmin = conc_adjust - 0.4,
xmax = conc_adjust + 0.4,
ymin = conc_min,
ymax = conc,
fill = status
),
colour = 'black', alpha = 0.8
) +
scale_y_log10() +
# Fake discrete axis
scale_x_continuous(labels = sort(unique(df$sites)),
breaks = 1:3) +
scale_fill_manual(name='Conc', values=c('positive'='orange', 'negative'='gray')) +
facet_grid(. ~ trop) +
theme_bw()
In ggplot, how to manage width of rectangle when scale is discrete?
Here I created a new column which is the numeric version of the factor column x
, but then used scale_x_continuous
to modify the axis such that it looks discrete.
library(ggplot2)
df <- data.frame(
x = c("a", "b", "c"),
y = c(1, 4, 2),
w = c(0.5, 1.2, 0.1)
)
df$xn <- as.numeric(df$x)
ggplot(df, aes(xmin = xn - w / 2,
xmax = xn + w / 2,
ymin = y,
ymax = y + 1,
fill = x)) +
geom_rect() +
scale_fill_discrete(guide = FALSE) +
scale_x_continuous(expand = c(0, 0.5),
labels = levels(df$x),
breaks = 1:length(levels(df$x))) +
coord_cartesian(xlim = c(1, length(levels(df$x))))
Related Topics
R: Finding the Intersect of Two Lines
Select a Sequence of Columns: ':' Works But Not 'Seq'
As.Date Produces Unexpected Result in a Sequence of Week-Based Dates
How to Configure R-3.0.1 with --Enable-R-Shlib
Adding an Image to a Datatable in R
Shiny Error in Match.Arg(Position):'Arg' Must Be Null or a Character Vector
R Read Abbreviated Month Form a Date That Is Not in English
Technique for Finding Bad Data in Read.CSV in R
How to Extend the 'Summary' Function to Include Sd, Kurtosis and Skew
How to Get Mean of Every N Rows and Keep the Date Index
R: Get the Min/Max of Each Item of a Vector Compared to Single Value
Getting Table() to Return Zeroes in R
Error:Could Not Find Build Tools Necessary to Build
Error: Could Not Find Build Tools Necessary to Build Dplyr
R Ggplot2 Using Italics and Non-Italics in the Same Category Label