I'm facing this problem with ggplot2 and plotly packages with R.
I'm creating a stacked bar chart, and, first of all, my data:
# here my data
family <- c('one','one','one','one','one','one','one','one',
'two','two','two','two','two','two','two','two')
group <- c('alpha','beta','alpha','beta','alpha','beta',
'alpha','beta','alpha','beta','alpha','beta',
'alpha','beta','alpha','beta')
field <- c('a','a','b','b','c','c','d',
'd','a','a','b','b','c','c','d','d')
value <- sample(1:10, 16, replace =TRUE)
data <- data.frame(family, group, field, value)
remove(family,group,field,value)
Then, I created my stacked barchart with ggplot2:
# here the plot
library(ggplot2)
library(plotly)
p <- ggplot(data, aes(x = group, y = value, fill =reorder(field,value)))
p <- p + geom_bar(position = "fill",stat = "identity")
p <- p + ggtitle("A simple example")
p <- p + theme(axis.text.x = element_text(angle = 90, hjust = 1))+ guides(fill=FALSE)
p <- p + facet_grid(family~.)
Lastly, I put it as a plotly output:
ggplotly(p)
remove(data)
The result is good:
My issue is: if you choose one of the occurrences on the legend you have this (choosing d):
I really would like that if you choose for example the d, the plot "returns" to a 100% stacked barplot, recalculating the percentage logically. Is it possible? If so, how?
Thanks in advance.
Related
I want to plot a segmented bar plot in ggplot2. Here is part of my dataframe, I want to plot the proportion of output(0 and 1) for each x1(0 and 1). But when I use the following code, what I plot is just black bars without any segmentation. What's the problem in here?
fig = ggplot(data=df, mapping=aes(x=x1, fill=output)) + geom_bar(stat="count", width=0.5, position='fill')
The output plot is here
You need factor variables for your task:
library(ggplot2)
df <- data.frame(x1=sample(0:1,100,replace = T),output=sample(0:1,100,replace = T))
ggplot(data = df, aes(x = as.factor(x1), fill = as.factor(output))) +
geom_histogram(stat = "count")+
labs(x="x11")
which give me:
I'm trying to plot a line graph (data points between 0 and 2.5, with interval of 0.5). I want to plot some bars in the same chart on the right-hand axis (between 0 and 60 with interval of 10). I am making some mistake in my code such that the bars get plotted in the left hand axis.
Here's some sample data and code:
Month <- c("J","F","M","A")
Line <- c(2.5,2,0.5,3.4)
Bar <- c(30,33,21,40)
df <- data.frame(Month,Line,Bar)
ggplot(df, aes(x=Month)) +
geom_line(aes(y = Line,group = 1)) +
geom_col(aes(y=Bar))+
scale_y_continuous("Line",
sec.axis = sec_axis(trans= ~. /50, name = "Bar"))
Here's the output
Thanks in advance.
Try this approach with scaling factor. It is better if you work with a scaling factor between your variables and then you use it for the second y-axis. I have made slight changes to your code:
library(tidyverse)
#Data
Month <- c("J","F","M","A")
Line <- c(2.5,2,0.5,3.4)
Bar <- c(30,33,21,40)
df <- data.frame(Month,Line,Bar)
#Scale factor
sfactor <- max(df$Line)/max(df$Bar)
#Plot
ggplot(df, aes(x=Month)) +
geom_line(aes(y = Line,group = 1)) +
geom_col(aes(y=Bar*sfactor))+
scale_y_continuous("Line",
sec.axis = sec_axis(trans= ~. /sfactor, name = "Bar"))
Output:
Here I have 2-dim numeric array dataset and numeric 1-dim array of labels clustring. Then I plot it with the following code:
s = data.frame(x = dataset[,1], y = dataset[,2])
p = ggplot(s, aes(x, y))
p + geom_point(aes(colour = factor(clustering)))
which displays beautiful picture:
Now I want to remove legend completely, so here I've found possible solution:
# Remove legend for a particular aesthetic (fill)
p + guides(fill=FALSE)
# It can also be done when specifying the scale
p + scale_fill_discrete(guide=FALSE)
# This removes all legends
p + theme(legend.position="none")
but none of such commands wont help. It shows empty plot instead:
So how do I remove the legend from my plot?
Try this:
library(ggplot2)
s = data.frame(x = rnorm(20), y = rnorm(20), clustering = rep(c(1, 2), 10))
p <- ggplot(s, aes(x, y))+
guides(fill=FALSE)+
geom_point(aes(colour = factor(clustering)))+
scale_fill_discrete(guide=FALSE)+
theme(legend.position="none")
p
In your code, you are not saving the plot again after each time you add something to it. You can fix this by changing the lines that add to the plot:
# Remove legend for a particular aesthetic (fill)
p = p + guides(fill=FALSE)
But the way I wrote is is more common R formatting.
Use show.legend = FALSE within geom_point. Here is an example using ggplot2's diamonds dataset.
s <- diamonds
p <- ggplot(data = s, aes(x = depth, y = price))
p + geom_point(aes(colour = factor(cut)), show.legend = FALSE)
Just try this:
p + geom_point(aes(colour = factor(clustering)),show.legend=FALSE)
This question already has answers here:
What is the simplest method to fill the area under a geom_freqpoly line?
(4 answers)
Closed 6 years ago.
I am plotting a continuous variable in X-axis against the the corresponding counts (not the density) in the Y-axis using ggplot2.
This is my code
p <- ggplot(matched.frame, aes(x = AGE, color = as.factor(DRUG_KEY))) + geom_freqpoly(binwidth=5)
p1 <- p + theme_minimal()
plot(p1)
This produces a graph like this this:
I want the areas under these lines to be filled with colors and with little bit of transparency. I know to do this for density plots in ggplot2, but I am stuck with this frequency polygon.
Also, how do I change the legends on the right side? For example, I want 'Cases' instead of 26 and Controls instead of '27'. Instead of as.factor(DRUG_KEY), I want it to appear as 'Colors"
Sample data
matched.frame <- data.frame("AGE"=c(18,19,20,21,22,23,24,25,26,26,27,18,19,20,24,23,23,23,22,30,28,89,30,20,23))
matched.frame$DRUG_KEY <- 26
matched.frame$DRUG_KEY[11:25] <- 27
You can use geom_ribbon to fill the area under the curves and scale_fill_discrete (fill color) as well as scale_color_discrete (line color) to change the legend labels:
library(ggplot2)
set.seed(1)
df <- data.frame(x = 1:10, y = runif(20), f = gl(2, 10))
ggplot(df, aes(x=x, ymin=0, ymax=y, fill=f)) +
geom_ribbon(, alpha=.5) +
scale_fill_discrete(labels = c("1"="foo", "2"="bar"), name = "Labels")
With regards to your edit:
ggplot(matched.frame, aes(x=AGE, fill=as.factor(DRUG_KEY), color=as.factor(DRUG_KEY))) +
stat_bin(aes(ymax=..count..,), alpha=.5, ymin=0, geom="ribbon", binwidth =5, position="identity", pad=TRUE) +
geom_freqpoly(binwidth=5, size=2) +
scale_fill_discrete(labels = c("26"="foo", "27"="bar"), name = "Labels") +
scale_color_discrete(labels = c("26"="foo", "27"="bar"), name = "Labels")
Is there any way to line up the points of a line plot with the bars of a bar graph using ggplot when they have the same x-axis? Here is the sample data I'm trying to do it with.
library(ggplot2)
library(gridExtra)
data=data.frame(x=rep(1:27, each=5), y = rep(1:5, times = 27))
yes <- ggplot(data, aes(x = x, y = y))
yes <- yes + geom_point() + geom_line()
other_data = data.frame(x = 1:27, y = 50:76 )
no <- ggplot(other_data, aes(x=x, y=y))
no <- no + geom_bar(stat = "identity")
grid.arrange(no, yes)
Here is the output:
The first point of the line plot is to the left of the first bar, and the last point of the line plot is to the right of the last bar.
Thank you for your time.
Extending #Stibu's post a little: To align the plots, use gtable (Or see answers to your earlier question)
library(ggplot2)
library(gtable)
data=data.frame(x=rep(1:27, each=5), y = rep(1:5, times = 27))
yes <- ggplot(data, aes(x = x, y = y))
yes <- yes + geom_point() + geom_line() +
scale_x_continuous(limits = c(0,28), expand = c(0,0))
other_data = data.frame(x = 1:27, y = 50:76 )
no <- ggplot(other_data, aes(x=x, y=y))
no <- no + geom_bar(stat = "identity") +
scale_x_continuous(limits = c(0,28), expand = c(0,0))
gYes = ggplotGrob(yes) # get the ggplot grobs
gNo = ggplotGrob(no)
plot(rbind(gNo, gYes, size = "first")) # Arrange and plot the grobs
Edit To change heights of plots:
g = rbind(gNo, gYes, size = "first") # Combine the plots
panels <- g$layout$t[grepl("panel", g$layout$name)] # Get the positions for plot panels
g$heights[panels] <- unit(c(0.7, 0.3), "null") # Replace heights with your relative heights
plot(g)
I can think of (at least) two ways to align the x-axes in the two plots:
The two axis do not align because in the bar plot, the geoms cover the x-axis from 0.5 to 27.5, while in the other plot, the data only ranges from 1 to 27. The reason is that the bars have a width and the points don't. You can force the axex to align by explicitly specifying an x-axis range. Using the definitions from your plot, this can be achieved by
yes <- yes + scale_x_continuous(limits=c(0,28))
no <- no + scale_x_continuous(limits=c(0,28))
grid.arrange(no, yes)
limits sets the range of the x-axis. Note, though, that the alginment is still not quite perfect. The y-axis labels take up a little more space in the upper plot, because the numbers have two digits. The plot looks as follows:
The other solution is a bit more complicated but it has the advantage that the x-axis is drawn only once and that ggplot makes sure that the alignment is perfect. It makes use of faceting and the trick described in this answer. First, the data must be combined into a single data frame by
all <- rbind(data.frame(other_data,type="other"),data.frame(data,type="data"))
and then the plot can be created as follows:
ggplot(all,aes(x=x,y=y)) + facet_grid(type~.,scales = "free_y") +
geom_bar(data=subset(all,type=="other"),stat="identity") +
geom_point(data=subset(all,type=="data")) +
geom_line(data=subset(all,type=="data"))
The trick is to let the facets be constructed by the variable type which was used before to label the two data sets. But then each geom only gets the subset of the data that should be drawn with that specific geom. In facet_grid, I also used scales = "free_y" because the two y-axes should be independent. This plot looks as follows:
You can change the labels of the facets by giving other names when you define the data frame all. If you want to remove them alltogether, then add the following to your plot:
+ theme(strip.background = element_blank(), strip.text = element_blank())