This is a basic question but I am unable to find an answer. I am generating about 9 barplots within one panel and each barplot has about 12 bars. I am providing all the 12 labels in my input but R is naming only alternate bars. This is obviously due to to some default setting in R which needs to be changed but I am unable to find it.
You may be able get all of the labels to appear if you use las=2 inside the plot() call. This argument and the others mentioned below are described in ?par which sets the graphical parameters for plotting devices. That rotates the text 90 degrees. Otherwise, you will need to use xaxt="n" (to suppress ticks and labels) and then put the labels in with a separate call to axis(1, at= <some numerical vector>, labels=<some character vector>).
# midpts <- barplot( ... ) # assign result to named object
axis(1, at = midpts, labels=names(DD), cex.axis=0.7) # shrinks axis labels
Another method is to first collect the midpoints and then use text() with xpd=TRUE to allow text to appear outside the plot area and srt be some angle for text rotation as named arguments to control the degree of text rotation:
text(x=midpts, y=-2, names(DD), cex=0.8, srt=45, xpd=TRUE)
The y-value needs to be chosen using the coordinates in the plotted area.
Copying a useful comment: For future readers who don't know what these arguments do: las=2 rotates the labels counterclockwise by 90 degrees. furthermore, if you need to reduce the font you can use cex.names=.5 to shrink the size down
To get rotated labels on a base R barplot, you could (like I do here) adapt one of the
examples given in the vignette of the gridBase package:
library(grid)
library(gridBase)
## Make some data with names long enough that barplot won't print them all
DD <- table(rpois(100, lambda=5))
names(DD) <- paste("long", names(DD), sep="_")
## Plot, but suppress the labels
midpts <- barplot(DD, col=rainbow(20), names.arg="")
## Use grid to add the labels
vps <- baseViewports()
pushViewport(vps$inner, vps$figure, vps$plot)
grid.text(names(DD),
x = unit(midpts, "native"), y=unit(-1, "lines"),
just="right", rot=50)
popViewport(3)
R won't label every bar if the labels are too big.
I would suggest trying to rotate the labels vertically by passing in the las=2 argument to your plotting function.
If the labels are still too large, you can try shrinking the font by using the cex.names=.5 argument.
Sample Data for plot
sample_curve <- c(2.31,2.34,2.37,2.52,2.69,2.81,2.83,2.85,2.94, 3.03, 3.21, 3.33) # create a sample curve
names(sample_curve)<-c("1 MO","2 MO","3 MO","6 MO","1 YR","2 YR","3 YR","5 YR","7 YR","10 YR","20 YR","30 YR") # label the curve
Example of plot with labels too big
barplot(sample_curve) # labels too big for the plot
Example of plot with labels rotated and small
barplot(sample_curve, las=2, cex.names=.5) # lables are rotated and smaller, so they fit
before plotting the barplot()
You can simply increase the margins with par() and your margins values (your plot has 4 margins) mar = c(v1,v2,v3,V4)
par(mar=c(10,4,4,4))
as example :
par(mar=c(10,4,4,4))
barplot(height=c(1,5,8,19,7),
names.arg=c("very long label 1","very long label 2",
"very long label 3","very long label 4",
"very long label 5"), las=2 )
Related
How can I make a Common legend for multiple plots? As I have plotted multiple plots but each plot is showing a single legend for itself as if I want to remove it and show a command legend.
And I also want to rename xlim to lon and ylim = lat. How can it be possible in image.plot?
This is my code
set.panel()
par(oma=c( 0,0,0,4)) # margin of 4 spaces width at right hand side
set.panel( 2,2) # 2X2 matrix of plots
# now draw all your plots using usual image command
for ( k in 1:4){
image.plot(lon, lat, pr2)
plot(shape,add=TRUE)
image.plot(lon, lat, pr1)
plot(shape,add=TRUE)
}
par(oma=c( 0,0,0,1))# reset margin to be much smaller.
image.plot( legend.only=TRUE, zlim=c(0,2000),horizontal = TRUE)
image.plot tricked into plotting in margin of old setting
set.panel() #
This is my image showing the plot:
If you call function hist on r, you will note that the box that usually surrounds plotting region doesn't appear, instead, only rulers indicating plot scale appear on the bottom and on the left. If you use r a lot you may probably have noticed this already. my question is: there is some graphical parameter or workaround to make this happen on any other plot of basic r (like in a scatterplot, a line plot, a qq plot or whatever)?
The only parameter I found was axes, but setting it to FALSE makes it disappear not only the box, but also the rulers.
You are looking for box().
op <- par(mfrow=c(1, 2))
hist(mtcars$mpg, sub="w/o box")
hist(mtcars$mpg, sub="w/ box")
box() ## <-- this
par(op)
the answer is bty graphical parameter:
x= matrix(rnorm(100), ncol= 2)
plot(x, bty= 'n')
This question already has an answer here:
Show element values in barplot
(1 answer)
Closed 4 years ago.
I have a barplot with grouped bars. Is it possible to include a label for each bar ? Example of plot without bar labels:
test <- structure(c(0.431031856834624, 0.54498742364355, 0.495317895592119,0.341002949852507, 0.40229990800368, 0.328769657724329,0.258600583090379,0.343181818181818, 0.260619469026549), .Dim = c(3L, 3L), .Dimnames = list(
c("2015", "2016", "2017"), c("a", "b", "c")))
barplot(test,ylim=c(0,1),beside=T)
p <- barplot(test, ylim=c(0, 1), beside=T)
text(p, test + .05*sign(test), labels=format(round(test, digits=2), nsmall=2))
The last line adds the labeling over the bar plots.
p takes the return values of the barplot() which are the x-axis bar positions.
In this example this is of the format 3x3 matrix.
text() needs then p for his x= argument. And for his y= argument it needs a slightly offsetted value than its bar plot heights (test). sign() determines the direction (above or below, +1 or -1) of the bar and .05 I determined empirically by trying, it is dependent on your values of the table.
So, x= and y= are the x and y coordinates for the labeling.
And finally, labels= determines which text should be printed.
The combination of format() and round() gives you full control over how many digits you want to display and that the display is absolutely regular in turns of number of digits displayed, which is not, if you use only round().
With xpd=T you could determine, whether labeling is allowed to go outside of region or not.
cex= could determine the fontsize of the label,
col= the colouring and font= the font.
alternatively, you can give just test for y= and determine via pos=3 that it should be above and offset=1 how many characterwidths the offset of the text shoul be.
p <- barplot(test, ylim=c(0, 1), beside=T)
text(x=p, y=test, pos=3, offset=1, labels=format(round(test, digits=2), nsmall=2))
You can find plenty of more instructions by looking into the documentation by
?text
# and
?barplot
in the R console
You can add a label using text function by extending your barplot. You can play with the parameters as you wish. Here is the sample code and its output.
x= barplot(test,ylim=c(0,1),beside=T)
text(x, test, labels=test, pos=1, offset=.5, col="red", srt = 90) #srt is used for vertical labels
If you really want to make a better plot, I would recommend ggplot as it has several other features like adding a theme to your plots and it is more easy for customizations.
If you're looking to label ever bar's category not it's value you can do something like this
allPermutations <- unlist(lapply(colnames(test), function(x) paste(x, rownames(test)) ))
barplot(test,ylim=c(0,1),beside=T, names.arg = allPermutations, las=2)
the file line gets all the combinations of categories. The plot call allows you to specify individual values with "names.arg" while las=2 rotates the names so it shows a bit nicer
So I have this plot which is showing average scores of group of people. I would like to know how to, in the same picture, plot or lable X (see the picture, I added X with paint), where X presents the mean of one student compared to others.
My code
CairoPDF(paste('output/picture/', student, '_hist.pdf', sep=''), family='sans',)
hist(means.students.all, xlab="Means", main="Average Ratings")
dev.off()
Here are two ways of adding a label. First, some random data and the regular histogram:
set.seed(0)
means <- rnorm(1000, 4.5, 0.2)
hist(means)
One way to add what you want is plot one point where you want, using points()
points(x=means[1], y=0, pch="X", cex=1.5)
Use y for the vertical position, pch for the type or character to plot, and cex to control it's size.
Another option, which gives you more possibilites, is using text()
text(x=means[2], y=0, label="StudentX", cex=1.5, srt=90, adj=c(0,0.5))
This way you can plot a full string (like the Student's name), rotate it 90 degrees using srt to fit the plot better, and align the text properly with left horizontal align and centered vertical align (this is related to the unrotated text) using adj. All of the above will result in:
Is there a way to add a histogram inside the plot area of another plot, but independent of the "base" plot's coordinate system? In my case, I want to add a histogram as a legend to a choropleth map (the histogram would show the number of regions that fall in each class), but the question could just as easily apply to any plot. For example
plot(1:10)
rect(1, 7, 4, 9, col="gray")
Could I make a histogram appear where the gray rectangle is in the above plot? Currently, if I try to create a histogram of the series 1:10, it appears using the coordinate system set by the scatterplot, and I can't figure out how (or whether it is possible) to reposition it and resize it to appear in the top left.
plot(1:10)
hist(1:10, col="gray90", add=TRUE)
Try subplot in the TeachingDemos package (and also replicated in the Hmisc package). subplot takes user coordinates but grconvertX / grconvertY can be used to convert from normalized plot coordinates. See comments below for additional discussion.
library(TeachingDemos)
plot(1:10)
subplot(hist(1:10), grconvertX(c(.1, .4), "npc"), grconvertY(c(.7, .9), "npc"))
which gives: