Shrink y axis width - r

Is it possible to shrink y-axis? I mean instead of the plot being square, I want it to be rectangular, with y axis shrinked.
library(ggplot2)
data = data.frame(rnorm(10000))
colnames(data) = "numOfX"
m <- ggplot(data, aes(x=numOfX))
m + geom_histogram(colour = "blue", fill = "white", binwidth = 0.5)

last_plot() + opts(aspect.ratio=1/10)

You can adjust the margins by adding the following to the last line of your code:
+ opts(plot.margin = unit(c(1,1,10,1), "lines"))
The numbers are the number of lines to add to the margin in the order c(top, right, bottom, left).
Update: The methods that baptiste and I discussed will change the size of the plot itself, but not the size of the plot area. Just for completeness, if you want to change the aspect ratio of the plot but still have it fill the whole plot area, then you need to change the size of the plot area itself.
On the Mac you can do quartz(width=w, height=h), with width and height in inches. This will open a plot window of the specified size. Then run your original code (without margin or aspect ratio changes). This will give you whatever plot size you wish and the plot will fill the plotting area. You can use dev.off() to close the Quartz window when you're done with it.
You can do the same thing in Windows using this Stack Overflow answer.
Finally, if you're using RStudio, you can do Export-->Copy-to-Clipboard and then adjust the aspect ratio manually.
Of course, you can use a combination of my or baptiste's original answers along with the methods above to control both the size of the plot area and the size of the margins at the same time.

Related

Rotate labels for histogram bars - shown via: labels = TRUE

Here is shown how to label histogram bars with data values or percents using labels = TRUE. Is it also possible to rotate those labels? My goal is to rotate them to 90 degrees because now the labels over bars overrides each other and it is unreadable.
PS: please note that my goal is not to rotate y-axis labels as it is shown e.g. here
Using mtcars, here's one brute-force solution (though it isn't very brutish):
h <- hist(mtcars$mpg)
maxh <- max(h$counts)
strh <- strheight('W')
strw <- strwidth(max(h$counts))
hist(mtcars$mpg, ylim=c(0, maxh + strh + strw))
text(h$mids, strh + h$counts, labels=h$counts, adj=c(0, 0.5), srt=90)
The srt=90 is the key here, rotating 90 degrees counter-clockwise (anti-clockwise?).
maxh, strh, and strw are used (1) to determine how much to extend the y-axis so that the text is not clipped to the visible figure, and (2) to provide a small pad between the bar and the start of the rotated text. (The first reason could be mitigated by xpd=TRUE instead, but it might impinge on the main title, and will be a factor if you set the top margin to 0.)
Note: if using density instead of frequency, you should use h$density instead of h$counts.
Edit: changed adj, I always forget the x/y axes on it stay relative to the text regardless of rotation.
Edit #2: changing the first call to hist so the string height/width are calculate-able. Unfortunately, plotting twice is required in order to know the actual height/width.

Alter axes in R with NMDS plot

I'm trying to change the axes in my NMDS plot to zoom into where my sites are plotted. I assume that the space chosen in a product of the species points which I do not have plotted. I have tried adding xlim to my code to no avail and was wondering if I have it in the wrong place or if another action is needed. Below is a copy of my code.
#NMDS on pooled abundance with NA's omitted
NMDS_HPA<-metaMDS(HP_Abundance_omit[,-1],k=2, trymax=1000)
plot(NMDS_HPA, type="n", display="sites", xlim=c(-1.5,1.5))
with(descriptors, levels(T))
colorvec<-c("seagreen4", "tan4", "mediumblue")
plot(NMDS_HPA, type="n", xlim=c(-1.5,1.5))
title(main="NMDS using Abundance with Bray-Curtis", sub="Habitats Pooled")
ordihull(NMDS_HPA, groups=treat, draw="polygon", col="grey90", label=F)
with(descriptors, points(NMDS_HPA, display="sites", col=colorvec[T], pch=21, bg=colorvec[T]))
with(descriptors, legend("topright", legend=levels(T), bty="n", col=colorvec, pch=21, pt.bg=colorvec))
Thanks
If you don't set the ylim too, then vegan has no choice but to show more (or less) of the x-axis than you want because the scaling of the axis must be retained; a unit change along one axis must match the same unit change along the other. Otherwise, how would you know how to represent Euclidean distances (easily) on the figure? As those Euclidean distances are supposed to reflect the rank ordering of the original dissimilarities, maintaining the aspect ratio or relative scaling of the axes to one another is important.
You can see this in action just by using your mouse to rescale the size of the device window on screen. R replots the figure using different axis limits all the time in order to maintain an aspect ratio of 1.
Consider this reproducible example:
library("vegan")
data(dune)
set.seed(56)
sol <- metaMDS(dune)
Choosing a section in both the x and y axes works as expected
## zoom in on the section (-0.5,0.5)(-0.5,0.5)
plot(sol, xlim = c(-0.5, 0.5), ylim = c(-0.5,0.5))
If you want to retain the full y-axis but only show say the middle 50% of the x axis then you have to plot on a device whose width is ~ 50% that of the height (approximately because R's default is to use different sized margins on the top/bottom left/right margins.)
png("~/mds-zoom2.png", height = 700, width = 350, res = 100, pointsize = 16)
plot(sol, xlim = c(-0.5, 0.5))
dev.off()
which produces
This is almost right. You could solve the problem exactly by setting the margins equal around the plot using par(mar = rep(4, 4) + 0.1) and then work out the ratio of the range of the scores on the x and y axes (get the scores(sol) and compute the range() on both columns then compute the ratio of the two ranges), then use that to give you the desired height of the plot for the width you want to state.
If you just plotted the points rather than the NMDS object than xlim works just fine
plot(NMDS_HPA$points, xlim=c(-1.5,1.5))

R Barplot with one bar - how to plot correctly

I want to plot a regular bar plot in R, but with just one bar. What I don't like is the fact that the bar width gets to be the width of the whole plot. I want the bar to be "thinner", but I don't know how to do it.
Default command is:
barplot(percentage, col=c("brown4"))
where percentage is a fraction. I tried using xlim parameter, but it gets very messy (bar goes completely to the right or left). For example, I tried:
barplot(percentage, col=c("brown4"), xlim=c(0.5,1))
but this stretches the bar even more. I am an R noob.
You may try to play around with the width of the device you plotting to. E.g.:
# plot to a Windows graphic device
windows(height = 10, width = 4)
barplot(0.5)
# plot to PDF
pdf(height = 10, width = 2)
barplot(0.5)
dev.off()
You may also try width together with xlim
barplot(0.5, width = 0.1, xlim = c(0, 1))
The width argument to barplot says:
width optional vector of bar widths. Re-cycled to length the number of bars drawn. Specifying a single value will have no visible effect unless xlim is specified.
So specify both width and xlim. The interaction of these two is not obvious (to me) so you will probably need to play around with them until they look like you want them to.
percentage <- 0.25
barplot(percentage, width=0.2, xlim=c(0,1.2), col="brown4")

Remove white space (i.e., margins) ggplot2 in R

I'm trying to plot a pie chart using GGPLOT2 in R. I want to do this in such a way as to omit the extra margin space.
What I'm doing is similar to what sharoz did in this post here except I want to include a legend.
Here is what I'm doing:
ggplot(DATA, aes(x=factor(0),fill=factor(LABELS),weight=VALUES)) +
geom_bar(width=1) +
coord_polar(theta='y') +
guides(fill=guide_legend(title='LEGEND'))
Assuming you are talking about the extra white space above and below the figure, the easiest solution is just to tweak the size of the graphics device. Here is aspect ratio is the key. If the aspect ratio of the graphics device matches that of the plot, you get rid of a lot of the whitespace.
What I use to save the plot is ggsave, in code:
ggplot(DATA, aes(x=factor(0),fill=factor(LABELS),weight=VALUES)) +
geom_bar(width=1) +
coord_polar(theta='y') +
guides(fill=guide_legend(title='LEGEND'))
ggsave("plot.png", width = 10, height = 5)
Just play around with width and height in ggsave until you are happy with the result.

Plotting fixed plot area

I have simple question, how can I plot fixed height barplots, i.e. stretching the plot area only change margins not the bararea, like the following:
> A <- 4
> plot (A)
> barplot(A, col = "green4")
When I strech are, bar area also get increases.
Edits: I want to keep the box size constant even the plot gets stretched.
by splitting the screen into multiple parts, you can achieve that partially:
split.screen(c(3,1))
A <- 4
barplot(A, col="green4")
Are you looking to just expand the y axis. Look at ylim?
What you might be looking for is to fix your aspect ratio. This can be achieved using asp:
barplot(A, col = "green4", asp = 1)
See also this post to R-help.
On a more philosophical note, when the height of the bar changes, there is no change in surface area. barplot only draws a sequence of bars, where the x axis is an ordinal (ordered categorical) variable which makes it impossible to calculate a surface area. The height of the bar is the only changing variable. I would recommend drawing these kinds of timeseries using a simple line plot.
So instead of:
a = runif(100)
b = 1:100
barplot(a)
use:
plot(b, a, type = "l")
or switch to my favorite plotting package, ggplot2:
require(ggplot2)
theme_set(theme_bw())
qplot(b, a, geom = "line")

Resources