R ggplotly Header Area Not Uniform - r

I have a ggplot with facet_wrap of about 22 different plots. I'm trying to make them interactive using ggplotly, but for some reason certain rows of plots have their header area get larger to the point where I barely see the graph. It looks like all the plots in the same row have the same gray sized area. I'm just trying to generate the plot, but keep the gray title area the same size. Any help would be greatly appreciated. I've tried to look at the panel options, but couldn't find anything that would do what I needed, but I'm not sure if I'm just missing something.
p <- ggplot(data = df, aes(value, fill = FIELD))+
geom_histogram()+
facet_wrap(~variable, scales='free_x')
ggplotly(p)
I was able to replicate the error with...
library(titanic)
library(reshape2)
titanic_long <- melt(titanic_train)
p<-ggplot(data=titanic_long, aes(value))+
geom_histogram(aes(fill=Sex))+
facet_wrap(~variable, scales='free_x')
ggplotly(p)

Related

Why does changing the label mess up my plot?

I have recently been playing around with various plot types using fictitious data to get my head around how I could display various pieces of information. One plot type that is gaining popularity is the so called individual differences dot plot which shows the change in each subjects score pre-post. The plot is fairly easy to produce, but my issue is that when I go to change the labels using either the labs or xlab ylab functions in ggplot, the plot itself becomes messed up. Below I have attached the fictitious data, the code used and the results.
Data
df<- data.frame(Participant<- c(rep(1:10,2)), Score<- c(rnorm(20,100,5)), Session<- c(1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2))
colnames(df) <- c("Participant", "Score", "Session")
Code for plot
p<- ggplot(df, aes(x=df$Session, y=df$Score, colour=df$Participant))+ geom_point()+
geom_line(group=df$Participant)+
theme_classic()
Plot
Individual difference plot
My dilemma is that anytime I try to change the label names, the plot messes up as per below.
Problem
p + xlab("Session") + ylab("Score")
Plot after relabelling
The same thing happens if I try the labs function i.e, p + labs(x= "Session", y= "Score"). You can see that the labels themselves do actually change, but for some reason this messes up the actual plot. Does any have any ideas as to what could be going wrong here?
The issue appears to be the grouping is undone when the label functions are called. Instead, issue the grouping as an aesthetic mapping:
library(dplyr); library(ggplot)
df %>% mutate(across(c(Session,Participant),factor)) -> df
p <- ggplot(df, aes(x=Session, y=Score, colour=Participant))+ geom_point()+
geom_line(aes(group=Participant))+
theme_classic()
p + xlab("Session") + ylab("Score")
I suspect this is probably a bug.

Geom_area plot doesn't fill the area between the lines

I want to make an area plot with ggplot(mpg, aes(x=year,y=hwy, fill=manufacturer)) + geom_area(), but I get this:
I'm realy new in R world, can anyone explain why it does not fill the area between the lines? Thanks!
First of all, there's nothing wrong with your code. It's working as intended and you are correct in the syntax required to do what you are looking to do.
Why don't you get the area geom to plot correctly, then? Simple answer is that you don't have enough points to draw a proper line between your x values for all of the aesthetics (manufacturers). Try the geom_point plot and you'll see what I mean:
ggplot(mpg, aes(x=year,y=hwy)) + geom_point(aes(color=manufacturer))
You need a different dataset. Here's a dummy one that is simply two lines with different slopes. It works as expected because each of the aesthetics has y values which span the x labels:
# dummy dataset
df <- data.frame(
x=rep(1:10,2),
y=c(seq(1,10,length.out=10), seq(1,5,length.out=10)),
z=c(rep('A',10), rep('B', 10))
)
# plot
ggplot(df, aes(x,y)) + geom_area(aes(fill=z))

How to add a shared x-axis and legend to ggplot (arrangegrob) and avoid different sized figures?

I,m trying to get these figures together in one figure, but I would like to have a shared x-axis below all 3, without the last figure to have a different size than the other 2. Similar for the middle figure with the legend, I would like the legend to be outide the 6 figure, without affecting the size of one of the figures.
I use arrangeGrob(plot1, plot2, ...., plot6) right now.
If anyone has a sollution, please let me know.
Thank you in advance!
use ggplot::facet_grid to share the axis and gridExtra::grid.arrange to plot them side by side
data(mtcars)
require(ggplot2)
require(gridExtra)
p1 <- ggplot(mtcars, aes(x = factor(vs), y = mpg)) +
geom_boxplot() +
facet_grid(cyl~.)
# Hope that i understood your question about the legend correctly
p2 <- ggplot(mtcars, aes(x = gear, y = mpg, col = factor(vs))) +
geom_point() +
facet_grid(cyl~.)
grid.arrange(p1,p2, nrow=1)
This is how far I got this time. The figure are indeed similar within each row. However, I would like all the six graphs to be the same size, but it is difficult due to fact that the left 3 need a legend and "long" x-axis labels. The right panel is just the way I would like it for both panels and with that the x-labels and legend outside of the box.
For example the graph below with the legend (pasted on the right side) and x-labels added to it, without changing the figures size or at least cause no differences between figure sizes

How to put labels of legend inside plot in ggplot2

Context: R/ggplot2.
Is there an automated way (or even a manual way) to put the legend factors inside the plot like the energies here (Co, 4,6,10,...), instead of having them in a regular legend box next to the plot ?
Source: Radiation Oncology Physics: A Handbook for Teachers and Students, EB. Podgorsak
So this seems close. I'd characterize this as "semi-automatic": there's definitely some tweaking needed, but most of the work is done for you...
The tricky bit is not placing the text labels (geom_text(...)), but creating the breaks in the plotted curves. This is done with geom_rect(...), where the width of the rectangles are set to the maximum label width, as determined using strwidth(...).
# create sample data
df <- data.frame(x=rep(seq(0,20,.01),5),k=rep(1:5,each=2001))
df$y <- with(df,x*exp(-x/k))
library(ggplot2)
eps.x <- max(strwidth(df$k)) # maximum width of legend label
eps.y <- eps.x*diff(range(df$y))/diff(range(df$x))
ggplot(df,aes(x,y))+
geom_line(aes(group=factor(k)))+
geom_rect(data=df[df$x==5,],
aes(xmax=x+eps.x, xmin=x-eps.x, ymax=y+eps.y, ymin=y-eps.y),
fill="white", colour=NA)+
geom_text(data=df[df$x==5,],aes(x,y,label=k))+
theme_bw()
If you want to color the lines too:
ggplot(df,aes(x,y))+
geom_line(aes(color=factor(k)))+
geom_rect(data=df[df$x==5,],
aes(xmax=x+eps.x, xmin=x-eps.x, ymax=y+eps.y, ymin=y-eps.y),
fill="white", colour=NA)+
geom_text(data=df[df$x==5,],aes(x,y,label=k), colour="black")+
scale_color_discrete(guide="none")+
theme_bw()

Grouped geom_boxplot from calculated values with mean

I created some grouped boxplots, basically for each dimension on the x axis I am showing various groups. Because my dataset is quite large, I had to precalculate the values for the boxes as ggplot did not have enough memory (I used ddply and did it in pieces).
I believe this is beter than just bar charts of the averages as it shows some of the variability.
I want 2 modifications, one was to not show the whisker lines, and I have done that by setting ymin=lower and ymax=upper.
I also wanted to add the means as well, but they show all in the center of each X category, and of course I want them each aligned with its box.
to make it easier on anyone helping, I recreated the same chart using mtcars - I tried position = "dodge" and "identity" with no change
Anyone knows how to do this? I searched and did not find a way. I am also attaching a picture of my latest chart. Code is below
data(mtcars)
data <- as.data.frame(mtcars)
data$cyl <- factor(data$cyl)
data$gear <- factor(data$gear)
summ <- ddply(data, .(cyl, gear),summarize, lower=quantile(mpg,probs=0.25,na.rm=T), middle=quantile(mpg,probs=.5,na.rm=T),upper=quantile(mpg,probs=.75,na.rm=T),avg=mean(mpg,na.rm=T))
p2 <- ggplot(summ, aes(x = cyl, lower = lower, middle = middle, upper = upper,fill=gear,ymin=lower,ymax=upper))+geom_boxplot(stat = "identity")
p2 <- p2 + geom_point(aes(x = cyl, y=avg, color=gear),color="red",position="dodge")
p2
The problem is that the width of the points is not the same as the width of the box plots. In that case you need to tell position_dodge what width do use. ?position_dodge gives a simple example of this using points and error bars, but the principle is the same for points and box plots. In your example, replacing position="dodge" with position=position_dodge(width=0.9) will dodge the points by the same amount as the box plots.

Resources