Change space between bars in histogram - R - r

I created a histogram in RStudio with the following code:
ggplot(data_csv, aes(x=Phasenew, fill=Success)) +
geom_histogram(binwidth = 1, position = "dodge", color="white")
What I want to do now, is to add more space between the bars of the histgram. I already tried the "width" parameter, but that one obviously does not work in histogram. Also I tried to make the outline bigger in white, but this will not show the correct length of the bar. Does anyone has an idea how to do that?

As two people wrote already in the comments, I also feel that your attempt to change the space between the 'bar' of a histogram is based on a misunderstanding about the nature of a histogram. Here the frequency of your events is represented as areas of the cells in the histogram. Or to quote Wikipedia:
the range of values—that is, divide the entire range of values into a series of intervals—and then count how many values fall into each interval
A priori these cells do not even need to have the same width (in the case your class widths would differ).
Perhaps what you are looking for is geom_bar (https://ggplot2.tidyverse.org/reference/geom_bar.html)
ggplot(data_csv, aes(x=Phasenew, fill=Success)) +
geom_bar()

Related

ggplot draw multiple plots by levels of a variable

I have a sample dataset
d=data.frame(n=rep(c(1,1,1,1,1,1,2,2,2,3),2),group=rep(c("A","B"),each=20),stringsAsFactors = F)
And I want to draw two separate histograms based on group variable.
I tried this method suggested by #jenesaisquoi in a separate post here
Generating Multiple Plots in ggplot by Factor
ggplot(data=d)+geom_histogram(aes(x=n,y=..count../sum(..count..)),binwidth = 1)+facet_wrap(~group)
It did the trick but if you look closely, the proportions are wrong. It didn't calculate the proportion for each group but rather a grand proportion. I want the proportion to be 0.6 for number 1 for each group, not 0.3.
Then I tried dplyr package, and it didn't even create two graphs. It ignored the group_by command. Except the proportion is right this time.
d%>%group_by(group)%>%ggplot(data=.)+geom_histogram(aes(x=n,y=..count../sum(..count..)),binwidth = 1)
Finally I tried factoring with color
ggplot(data=d)+geom_histogram(aes(x=n,y=..count../sum(..count..),color=group),binwidth = 1)
But the result is far from ideal. I was going to accept one output but with the bins side by side, not on top of each other.
In conclusion, I want to draw two separate histograms with correct proportions calculated within each group. If there is no easy way to do this, I can live with one graph but having the bins side by side, and with correct proportions for each group. In this example, number 1 should have 0.6 as its proportion.
By changing ..count../sum(..count..) to ..density.., it gives you the desired proportion
ggplot(data=d)+geom_histogram(aes(x=n,y=..density..),binwidth = 1)+facet_wrap(~group)
You actually have the separation of charts by variable correct! Especially with ggplot, you sometimes need to consider the scales of the graph separately from the shape. Facet_wrap applies a new layer to your data, regardless of scale. It will behave the same, no matter what your axes are. You could also try adding scale_y_log10() as a layer, and you'll notice that the overall shape and style of your graph is the same, you've just changed the axes.
What you actually need is a fix to your scales. Understandable - frequency plots can be confusing. ..count../sum(..count..)) treats each bin as an independent unit, regardless of its value. See a good explanation of this here: Show % instead of counts in charts of categorical variables
What you want is ..density.., which is basically the count divided by the total count. The difference is subtle in principle, but the important bit is that the value on the x-axis matters. For an extreme case of this, see here: Normalizing y-axis in histograms in R ggplot to proportion, where tiny x-axis values produced huge densities.
Your original code will still work, just substituting the aesthetics I described above.
ggplot(data=d)+geom_histogram(aes(x=n,y=..density..,)binwidth = 1)+facet_wrap(~group)
If you're still confused about density, so are lots of people. Hadley Wickham wrote a long piece about it, you can find that here: http://vita.had.co.nz/papers/density-estimation.pdf

How to enlarge the size of facet in R

I'm working on the following dataset where each facet shows the bleaching for one kind of coral at one site across the time period. My problem is how to enlarge the size of each facet to see the trend more clearly, as in current facets, it is hard to see the trend because of the small change in bleaching....
here is my code,
cb1<-aggregate(cb$latitude, list(Site=cb$site), mean)
cb$site=factor(cb$site, levels=cb1$Site[order(cb1$x)])
ggplot(cb,aes(year,bleaching)) +
geom_point() +
facet_grid(site~kind) +
geom_smooth(method="lm",color="grey") +
coord_cartesian(ylim=c(0,1))
due to the current size of the grid of facets, some lines seem flat but actually they are not.
You cannot really increase the sizes of the facets unless you increases the size of the plot overall. One option would be to save a large version of the plot:
p<-ggplot(cb,aes(year,bleaching))+geom_point()+facet_grid(site~kind)+geom_smooth(method="lm",color="grey")+coord_cartesian(ylim=c(0,1))
ggsave("file_name.jpg", plot = p, width = 24, height = 24, units = "in")
If you have limited space (e.g. the plot has to go on an A4 sheet) then the facet_grid_paginate function from ggforce would be a good option. It allows you to split faceted plots over multiple pages. You can define the number of rows and columns per page. See this link.
Alternatively, if you want to show that the lines are not flat more clearly, you can try toying with a couple of the arguments to facet_grid. facet_grid allows you to set the scales to free, free_x or free_y. Setting free_y would mean that each facet has its own y-axis (not necessarily between 0 and one (assuming you also removed the ylim=c(0,1). This would, however, make the the facets more difficult to compare with each other.

geom_bar not showing every values

I want to draw a bar plot, with ggplot and geom_bar, but it seems that the behavior of geom_bar is not consistent. I don't understand why.
My data is a time series of precipitations:
library(ggplot2)
library(data.table)
library(lubridate)
set.seed(42)
dt1 <- data.table(dateHeure=seq(ymd_hms("2014-06-04 13:30:00"),
ymd_hms("2014-10-20 08:30:00"), by='1 hour'),
rain=sample(c(rep(5,15), rep(10,15), rep(20,10),
rep(30, 5), 40, rep(0, 3262))))
Then i plot it, and not all the data appears... Why is some data missing?
ggplot(data=dt1)+
geom_bar(aes(x=dateHeure, y=rain),
stat="identity",
fill="blue") # doesn't work!
But if i add the variable color in aes, then the plot is correct!
ggplot(data=dt1)+
geom_bar(aes(x=dateHeure, y=rain, color="rain"),
stat="identity",
width=0.2) # work properly
So someone know why geom_bar doesn't work properly without color? Because i can't rely on it if sometimes not all the data is correctly plotted...
thanks!
edit: to respond to #eipi10, i added the plots. The strange thing is that when i resize the plot window in the first case, the data which is plotted changes!
Based on the edit to your question, I think I know what's happening: In the first plot, you use fill="blue". But the bin widths are very small compared to the overall range of the x-axis. This results in very, very thin vertical bars--so thin that you can't see some of them on your screen, but they appear when you expand the physical width of the plot.
On the other hand, in your second plot you used colour="rain", which adds a border to each bar, making each bar thicker, so they are visible, even when the physical width of the plot is relatively small.
Try adding colour="blue"(or "red" or whatever) to your first plot and I think you'll see all the bars, even without resizing. On the other hand, try changing colour="rain" to fill="rain" on your second plot and see if that creates the "disappearing data" effect on your second plot.
UPDATE: In response to your comment, you can use the colour parameter and then set the line width to get exactly the bar thickness you want, so you don't really need fill. For example:
ggplot(data=dt1)+
geom_bar(aes(x=dateHeure, y=rain),
stat="identity",
colour="blue", lwd=0.5)
Just set lwd (line width) to a value that gives you the bar-width you want. And, of course, you can also change the colour as well.

keep colour palette constant between plots

I need to compare two maps of the same quantities, I would like to keep the colour palette constant in the two graphs, for easing comprehension, but it looks like I don't get how to do so.
Should I set limits (e.g. the minimum between all the plots assigned to low and the highest level to high?)
Is there an easy way to do so?
I am new to this, so sorry if the solution is banal, I went through a lot of blog posts but looks like I am not finding anything.
My code:
fin<-get_map("Helsinki",zoom=12)
ggmap(fin, legend="bottom")+
geom_polygon(data=a,aes(x=a$long,y=a$lat, id=id, fill=Test_statistics), alpha=0.1, colour="white")
To give you an idea, this is an image
and this is another
it is not clear at all!
Images still need a bit of "prettyfying" it is just to give an idea
Basically what I would like is in this question, but for discrete (factor) values
I can't reproduce your plots because you've not given us the data, but setting limits in a scale_colour_gradient should work. See:
http://docs.ggplot2.org/0.9.3.1/scale_gradient.html
under "Tweak scale limits" (second example) where Hadley says:
Setting the limits manually is also useful when producing
multiple plots that need to be comparable
For example (and I'm using points here for simplicity - you probably have to use scale_fill_gradient to set the fill colour for polygons - I don't have the time to build some polygons):
> set.seed(310366); d=data.frame(x=runif(20),y=runif(20),
z1=rnorm(20), z2=rnorm(20)+5)
note that z1 has a range of about -1 to 1, and z2 has a range of 4 to 7. This helps us see the effect.
> ggplot(d,aes(x=x,y=y,col=z1))+geom_point(size=8) +
scale_colour_gradient(limit=range(c(d$z1,d$z2))
> ggplot(d,aes(x=x,y=y,col=z2))+geom_point(size=8) +
scale_colour_gradient(limit=range(c(d$z1,d$z2)))
produces two plots with the same limits on the palette legend, but the first one has very dark points because the values are all low (-1 to 1) and the second one has mostly light colours because the values are all high (4 to 7).
Both sets of points have been coloured using the same mapping of value to colour because of the limit argument in the scale_colour_gradient function. You are mapping the fill attribute so I think you need scale_fill_gradient.
I didnt get your problem exctly, but try adding this to all your plots. Then the colour code should be uniform.
+scale_colour_brewer(pallette="Set1")
You can add any of the pallette's shown here with examples
http://www.cookbook-r.com/Graphs/Colors_(ggplot2)/#color-charts

Adjusting the relative space of facets (without regard to coordinate space)

I have a primary graph and some secondary information that I want to facet in another graph below it. Facetting works great except I do not know how to control the relative space used by one facet versus another. Am aware of space='free' but this is only useful if the ranges correspond to the desired relative sizing.
So for instance, I may want a graph where the first facet occupies 80% and the second 20%. Here is an example:
data <- rbind(
data.frame(x=1:500, y=rnorm(500,sd=1), type='A'),
data.frame(x=1:500, y=rnorm(500,sd=5), type='B'))
ggplot() +
geom_line(aes(x=x, y=y, colour=type), data=data) +
facet_grid(type ~ ., scale='free_y')
The above creates 2 facets of equal vertical dimension. Adding in space='free' in the facet_grid function changes the dimensions such that the lower facet is roughly 5x larger than the upper (as expected).
Supposing I want the upper to be 2x as large, with the same data set and ordering of facets. How can I accomplish this?
Is the only way to do this with some trickery in rescaling the data set and manually overriding axis labels (and if so, how)?
Alternative
As indicated below can use viewports to render as multiple graphs. I had considered this and in-fact had implemented using this approach in the past with standard plot and viewports.
The problem is that it is very difficult to get x-axis to align with this approach. So if there is a way to fix the size of the y-axis label region and the size of the legend region, can produce 2 graphs that have the same rendering area.
You don't need to use facets for this - you can also do this by using the viewport function.
> ratio = 1/3
> v1 = viewport(width=1,height=ratio,y=1-ratio/2)
> v2 = viewport(width=1,height=1-ratio,y=(1-ratio)/2)
> print(qplot(1:10,11:20,geom="point"),vp=v1)
> print(qplot(1:10,11:20,geom="line"),vp=v2)
Ratio is the proportion of the top panel to the whole page. Try 2/3 and 4/5 as well.
This approach can get ugly if your legend or axis labels in the two plots are different sizes, but for a fix, see the align.plots function in the ggExtra package and ggplot2 author Hadley Wickam's notes on this very topic.
There's no easy way to do this with facets currently, although if you are prepared to go down to editing the Grid, you can modify the ggplot graph after it has been plotted to get this effect.
See also this question on using grid and ggplot2 to create join plots using R.
Kohske Takahashi posted a patch to facet_grid that allows specification of the relative sizing of facets. See the thread:
http://groups.google.com/group/ggplot2/browse_thread/thread/7c5454dcc04bc7b8
With luck we'll see this in a future version of ggplot2.

Resources