R: vertical x labels out of plot - r

I have a plot where I have introduced vertical x axis labels via las = 2. Those labels are words. Category words. These words are too long, they range out of the picture. I have no main title in my plot (not needed), so there is enough room at the top of the image. But how do I shift everything up? I find code for parameters called mai and mar. But they do not change anything.
I tried to use mar by setting the third value of mar ("top") to 0. So I want 0 margin at the top. But the plot stays where it is :/
Here is my code (german words for the x labels):
categories <- c("Introvertiert", "Selbstbewusst", "Kooperativ", "Ehrgeizig",
"Einfühlsam", "Autoritär", "Temperamentvoll", "Flexibel", "Tolerant", "Teamfähig",
"Zielorientiert", "Überheblich", "Vielseitig", "Ungeduldig", "Zuverlässig", "Eigensinnig",
"Anpassungsfähig", "Souverän", "Selbstkritisch", "Entscheidungsfreudig", "Intelligent",
"Kontaktfreudig", "Kreativ", "Stressresistent", "Hilfsbereit", "Emotional",
"Kompromissbereit", "Gesellig", "Standhaft", "Pünktlich", "Unruhig", "Tatkräftig",
"Aufgeschlossen", "Fröhlich", "Zuvorkommend", "Uneigennützig", "Selbstbeherrscht",
"Schüchtern", "Freundlich", "Sprachgewandt")
x <- seq(1,40)
y <- seq(1,40)
plot(x,y,xaxt="n",main="", mar=c(5, 4, 0, 2) + 0.1, xlab ="")
axis(1, at=1:40, labels=categories, las = 2, cex.axis = 0.8)

Use par:
#save old settings
op <- par(no.readonly = TRUE)
#change settings
par(mar=c(8, 4, 2, 2) + 0.1)
plot(x,y,xaxt="n",main="", xlab ="")
axis(1, at=1:40, labels=categories, las = 2, cex.axis = 0.8)
#reset settings
par(op)

Related

Reduce space between names.arg and axis (box) in barplot

I created a simple barplot surrounded by a box. Is there any way to move my names closer to the box (space marked in blue)?
MWE:
set.seed(1)
count <- runif(n = 3, min = 0, max = 10)
names <- letters[seq(from = 1, to = 3)]
barplot(height = count,
names.arg = names,
horiz = TRUE,
las = 1)
box()
Here are two ways to do this. You can use rect instead of box to move the box boundary to the left:
barplot(height=count, names.arg=names, horiz=TRUE, las=1)
bounds <- par("usr")
rect(bounds[1]-.1, bounds[3], bounds[2], bounds[4], xpd=NA)
Or you can add the y-axis separately which lets you control where the labels are plotted:
x <- barplot(height=count, horiz=TRUE, las=1)
box()
axis(2, x, names, las=1, tick=FALSE, mgp=c(2, .35, 0))
Adjust the middle value in mgp to position the labels (see ?par)

Points Scale in R barplot [duplicate]

This question already has answers here:
How can I plot with 2 different y-axes?
(6 answers)
Closed 6 years ago.
i'm having troubles in a multi axis barplot. I have an X,Y axis with bars and dots in the same graph. The point is that I have to shown both of them in different scales
While I can shown both (bars and dots) correctly, the problem comes when I try to set different scales in left and right axis. I dont know how to change the aditional axis scale, and how to bind the red dots to the right axis, and the bars to the left one.
This is my code and what I get:
labels <- value
mp <- barplot(height = churn, main = title, ylab = "% churn", space = 0, ylim = c(0,5))
text(mp, par("usr")[3], labels = labels, srt = 45, adj = c(1.1,1.1), xpd = TRUE, cex=.9)
# Population dots
points(popul, col="red", bg="red", pch=21, cex=1.5)
# Churn Mean
media <- mean(churn)
abline(h=media, col = "black", lty=2)
# Population scale
axis(side = 4, col= "red")
ylim= c(0,50)
ylim= c(0,5)
What I want is to have left(grey) axis at ylim=c(0,5) with the bars bound to that axis. And the right(red) axis at ylim=c(0,50) with the dots bound to that axis...
The goal is to represent bars and points in the same graph with diferent axis.
Hope I explained myself succesfully.
Thanks for your assistance!
Here is a toy example. The only "trick" is to store the x locations of the bar centers and the limits of the x axis when creating the barplot, so that you can overlay a plot with the same x axis and add your points over the centers of the bars. The xaxs = "i" in the call to plot.window indicates to use the exact values given rather than expanding by a constant (the default behavior).
set.seed(1234)
dat1 <- sample(10, 5)
dat2 <- sample(50, 5)
par(mar = c(2, 4, 2, 4))
cntrs <- barplot(dat1)
xlim0 <- par()$usr[1:2]
par(new = TRUE)
plot.new()
plot.window(xlim = xlim0, ylim = c(0, 50), xaxs = "i")
points(dat2 ~ cntrs, col = "darkred")
axis(side = 4, col = "darkred")

Rotate axis label upside down in R base plot

I need some help with axis labels in base R plotting, thanks in advance for any guidance!
What I need:
In R base plot() I would like to rotate my axis(3, ...) label to -90 degrees to get the following output:
(note that I have rotated the pic outside R)
Why I need it (big picture):
I am using labcurve for curve annotation and strangely enough for my data the annotation results are visually waay better if applied to the -90 degree rotated graph. After running labcurve I can rotate the resulting R-generated PDF back 90 degrees in LaTeX.
What I have tried:
#1
I know that this is governed by the las option in par with the following options:
0: always parallel to the axis [default],
1: always horizontal,
2: always perpendicular to the axis,
3: always vertical.
However, these four options available only cover the two angles 0 and 90 degrees as either of the following:
plot(x=c(0,10), y=c(0,1), type='n', xlab='',ylab='', axes=FALSE)
lines(x=c(0,7,7,10), y=c(0,0.33,0.67,1))
axis(2, at=c(0,1), labels=c('',''), las=2)
xlabels <- c('0','10')
axis(3, at=c(0,10), labels=xlabels, las=0)
or
axis(3, at=c(0,10), labels=xlabels, las=1)
axis(3, at=c(0,10), labels=xlabels, las=2)
or
axis(3, at=c(0,10), labels=xlabels, las=3)
#2:
One could think of str but according to the doc:
Note that string/character rotation via argument srt to par does not
affect the axis labels.
Thanks again!
The general procedure for creating rotated axis labels is described in R FAQ 7.27. Here's a modified example which hopefully suits your needs.
# some toy data
x <- c(0, 2, 6, 10)
y <- sample(1:4)
# Increase top margin to make room for rotated labels
par(mar = c(5, 4, 7, 2) + 0.1)
# Create plot without axis or labels
plot(x, y, type = "l", axes = FALSE, xlab = "", ylab = "")
# positions for tick marks
atx <- range(x)
aty <- range(y)
# x axis without labels
axis(side = 3, at = atx, labels = FALSE)
# y axis without labels
axis(side = 2, at = aty, labels = FALSE)
# add -90 rotated x axis labels
text(x = atx, y = par("usr")[4] + 0.25, srt = -90, adj = 1,
labels = atx, xpd = TRUE)

Moving an R plot side to side

I'm using plot() to create a map with a legend and because of the shape of the map, it overlaps with the legend. I'm still learning R, but how can I move the map slightly to the left to reduce overlap? I'm sure there's a simple fix, but I was not able to find the right parameter.
Thanks for your help! I'm new to R (and stackoverflow) so I cannot post an image unfortunately.
EDIT: Here's the code that I'm running:
plot(spdfCounties, bg="gray90", col=findColours(ciFisher, colRamp))
title("Fisher-Jenks")
strLegend = paste(
"$", format(round(ciFisher$brks[-(intClasses + 1)]), big.mark=","), " - ",
"$", format(round(ciFisher$brks[-1]), big.mark=","), sep=""
)
legMain = legend(
"topright", legend=strLegend,
title="Median Income, 2010", bg="gray", inset=0.02, cex=0.6,
fill=colRamp
)
Use the mar (for margin) options in par. From ?par
mar A numerical vector of the form c(bottom, left, top, right) which
gives the number of lines of margin to be specified on the four sides
of the plot. The default is c(5, 4, 4, 2) + 0.1.
So, if your legend is on the right, make your right margin bigger by entering
par(mar = c(5, 4, 4, 8) + 0.1)
Some trial and error should be able to get it right.
This question about resetting par values may also be helpful. In general, you can always do dev.off() to close the device, and a new device will start with the default par settings.
EDIT: Adapting #Hugh's example
x <- runif(1000)
y <- runif(1000)
plot(x, y)
legend('topright', legend = "points") # overlaps points
par(mar = c(5, 4, 4, 8) + 0.2)
plot(x, y)
legend('right', legend = "points", inset = -.3, xpd = T)
# The correct right margin and inset value will depend
# on the size of your graphic device.
Adjusting the margins results in
Adding white space to the graph, as in #Hugh's answer, looks like this:
Edit 2
Trying to adapt new code from question. You're still using base graphics' plot function, so nothing should be special about having a map. However, we don't have your data, so we can't really test anything. (If this doesn't work---and regardless before posting another question---you should look at tips for making reproducible examples.)
dev.off() # to reset par
par(mar = c(5, 4, 4, 8))
plot(spdfCounties, bg="gray90", col=findColours(ciFisher, colRamp))
# the margins are set as soon as you call plot()
title("Fisher-Jenks")
strLegend = paste(
"$", format(round(ciFisher$brks[-(intClasses + 1)]), big.mark=","), " - ",
"$", format(round(ciFisher$brks[-1]), big.mark=","), sep=""
)
legMain = legend(
"right", # changed the legend to right
legend=strLegend,
title="Median Income, 2010",
bg="gray",
inset= -0.3, # negative inset to put it outside of the plotting region
xpd = T, # xpd set to allow plotting outside of the plot region
cex=0.6,
fill=colRamp
)
As a one off, you can change the lim arguments of plot to create more space.
x <- runif(1000)
y <- runif(1000)
plot(x,y)
legend('topright', legend = "points") # overlaps points
plot(x,y, xlim = c(0, 1.5), ylim = c(0, 1.5) # adds white space
legend('topright', legend = "points")

R changing format of scale on y-axis

I have a plot that has $-amounts and dates on y and x axis respectively. Currently the dollar amounts range from $0-15 million. Something like this:
x <- rnorm(20)^2 * 1000000
plot(x)
R does stuff like '1.0e+07' instead of '10,000,000' and also orients the text vertically instead of horizontally.
My questions are:
1) how would I get the scale text to be horizontally oriented?
2) how would I get R to use 10MM instead of '10,000,000' or '1.0e+07'?
1) See the scipen option in ?options which is a penalty against the use of scientific notation. For better control, you need to plot the axis by hand with labels you want.
2) See las in ?par which controls to orientation crudely of axis labels.
For 1):
x <- rnorm(20)^2 * 10000000
layout(matrix(1:2, ncol = 2))
plot(x)
getOption("scipen")
opt <- options("scipen" = 20)
getOption("scipen")
plot(x)
options(opt)
layout(1)
which gives
To plot your own axis try
plot(x / 10000000, axes = FALSE)
axis(1)
pts <- pretty(x / 10000000)
axis(2, at = pts, labels = paste(pts, "MM", sep = ""))
box()
Which gives
Where we use pretty() to select pretty locations for the ticks just as R would and then add a custom axis. Notice how we suppress axis drawing in the plot() call and then add back the axes and the plot frame with calls to axis() and box().
For 2) combining with 1)
opt <- options("scipen" = 20)
op <- par(mar = c(5,7,4,2) + 0.1) ## extra margin to accommodate tick labs
x <- rnorm(20)^2 * 10000000
plot(x, las = 1, ylab = "") ## no y-axis label
title(ylab = "label", line = 5.5) ## need to plot the axis label
par(op)
options(opt)
Which gives
Notice how we use las in the plot() call, and we need to create some extra margin space to accommodate the tick labels. We also need to plot the label by hand otherwise R will stick it in amongst the tick labels.
For the custom axis labels, add the las = 1 to the axis() call:
op <- par(mar = c(5,5,4,2) + 0.1)
plot(x / 10000000, axes = FALSE, ylab = "")
axis(1)
pts <- pretty(x / 10000000)
axis(2, at = pts, labels = paste(pts, "MM", sep = ""), las = 1)
title(ylab = "my label", line = 4)
box()
par(op)
Which produces
Use axis with custom labels. First, divide your data by 1 million. And then create a series with the MM notation using paste()
y <-rnorm(20)^2 * 1000000 /1000000
x <-11:30
plot(x,y, yaxt="n")
my.axis <-paste(axTicks(2),"MM",sep="")
axis(2,at=axTicks(2), labels=my.axis)
The text is now horizontal. But if you run into a problem use, las=1 to force labels to be horizontal.
axis(2,at=axTicks(2), labels=my.axis, las=1)

Resources