hist generates a histogram with the vertical boundaries of bars plots. If I don't want to draw the vertical boundaries that are common between adjacent bars, is there a way to do so?
If you want to retain the outline, it's pretty trivial to draw a polygon over the histogram:
set.seed(1)
h <- hist(rnorm(50))
polygon(rep(h$breaks, each = 2), c(0, rep(h$counts, each = 2), 0), col = "gray")
First some reproducible data:
set.seed(42)
x <- rnorm(100, 15, 4)
The border= argument is documented on the manual page for hist (?hist):
hist(x, border="lightgray")
No border.
Related
I've been trying to color specific bins above a defined threshold in the following data frame (df)
df <- read.table("https://pastebin.com/raw/3En2GWG6", header=T)
I've been following this example (Change colour of specific histogram bins in R), but I cannot seem to get this to adapt their suggestions to my data, so I wanted to ask you here at stackoverflow
I would like all bins with values above 0.100 to be "red", and the rest all to be either no color, or just black (I defined black, but I would prefer no color)
Here is what I tried:
col<-(df$consumption>=0.100)
table(col) # I can see 40 points above 100, the rest below
col[which(col=="TRUE")] <- "firebrick1"
col[which(col=="FALSE")] <- "black"
hist(df$consumption, breaks = 1000, xlim = c(0,0.2), col=col,xlab= "Consumption [MG]")
However, the whole graph is red, and that doesn't make sense..?
In other words, I would like anything to the right side of the line below to be red
hist(df$consumption, breaks = 1000, xlim = c(0,0.2),xlab= "Consumption [MG]")
abline(v=c(.100), col=c("red"),lty=c(1), lwd=c(5))
Simply plot two histograms on top of each other using add=TRUE and sub-setting the second.
hist(df$consumption, breaks=1000, xlim=c(0,.2),xlab= "Consumption [MG]")
hist(df$consumption[df$consumption > .100], breaks=1000, xlim=c(0,.2), col=2, add=TRUE)
abline(v=.100, col=2, lty=3)
Here is along the lines of what you were doing. You do not want to count the points above your cutoff, but rather the number of histogram bins above your cutoff.
# store the histogram as an object
h <- hist(df$consumption, breaks = 1000)
# extract out the breaks, and assign a color vector accordingly
cols <- ifelse(h$breaks > 0.1, "firebrick1", "black")
# use the color vector
plot(h, col = cols, xlim=c(0,.2),xlab= "Consumption [MG]")
abline(v=c(.100), col=c("red"),lty=c(1), lwd=c(5))
Hi I guess that I have quite a rudimentary question here.
I have a plot like this
but as you could easily notice, some of the label could not be displayed (some are overlapped with the symbols, some are just out of the figure frame)
I noticed that there are some way to adjust the position of labels
text(tsne_out$Y[,1], tsne_out$Y[,2], labels=samplegrouptry, pos=1)
for example, I could specify the the value of "pos" (from 1 to 4). I guess they are good enough in most cases .But I wonder whether there are some better ways to do that.
Any suggestion, thanks!
Following the suggestion from
vas_u Through change the axis ranges as well as "pos", I could get better plot:
One way around the problem would be to enlarge the axes of the plot.
Your example approximately reproduced with dummy data:
x <- rnorm(16, mean = 0)
y <- rnorm(16, mean = 1)
# Initial scatterplot with text labels out of plot area:
plot(x, y, pch = 16)
text(x, y, labels = paste("Name", 1:16), pos = 1) # Some labels outside plot area
# Second plot with the X and Y axes gently expanded:
plot(x, y, pch = 16,
xlim = 1.1*range(x),
ylim = 1.1*range(y))
text(x, y, labels = paste("Name", 1:16), pos = 1) # Labels now fit inside!
I hope this helps.
I would like to plot a distribution of counts using the barplot function in R, and underlay it with a boxplot to include information on median, quartiles, and outliers. A not-too-elegant solution for this has been found for histogram and boxplots: http://rgraphgallery.blogspot.com/2013/04/rg-plotting-boxplot-and-histogram.html.
There are many places online where one can find the argument being made that numerical data should be plotted with histograms while categorical data should be plotted with bar plots. My data are numerical, and in fact on a ratio scale (as they are counts), but because they are discrete, I want columns with gaps, not columns that touch, which seems to be the only option for histogram().
I currently have the following, but bar- and boxplot do not align quite perfectly:
set.seed(476372)
counts1 <- rpois(10000,3)
nf <- layout(mat = matrix(c(1,2),2,1, byrow=TRUE), height = c(3,1))
par(mar=c(3.1, 3.1, 1.1, 2.1))
barplot(prop.table(table(counts1)))
boxplot(counts1, horizontal=TRUE, outline=TRUE,ylim=c(0,12), frame=F, width = 10)
Here my question: How can I make them align?
Another option that's similar but a little more work. This preserves the option for gaps between the bars:
tbl <- prop.table(table(counts1))
left <- -0.4 + do.call('seq', as.list(range(counts1)))
right <- left + (2 * 0.4)
bottom <- rep(0, length(left))
top <- tbl
xlim <- c(-0.5, 0.5) + range(counts1)
nf <- layout(mat = matrix(c(1,2),2,1, byrow=TRUE), height = c(3,1))
par(mar=c(3.1, 3.1, 1.1, 2.1))
plot(NA, xlim=xlim, ylim=c(0, max(tbl)))
rect(left, bottom, right, top, col='gray')
boxplot(counts1, horizontal=TRUE, outline=TRUE, ylim=xlim, frame=F, width = 10)
Maybe using a "fake" histogram at the end
ht=hist(counts1,breaks=12,plot = F)
ht$counts=as.numeric(table(counts1))
ht$density=as.numeric(prop.table(table(counts1)))
ht$breaks=as.numeric(names(table(counts1)))
ht$mids=sapply(1:(length(ht$breaks)-1),function(z)mean(ht$breaks[z:(z+1)]))
plot(ht,freq=F,col=3,main="")
boxplot(counts1, horizontal=TRUE,outline=TRUE,ylim=range(ht$breaks), frame=F, col="green1", width = 10)
For example, I have the following simple command:
x<-rnorm(2000, 0, 30)
hist(x)
But the graph shows a gap between the line y=0 and the x-axis. I want it to be shown in the normal format, where the two axes touch on each other at a particular point (x0, y0) which I can specify arbitrarily. What is the option in R to do that?
Thank you.
One way is to plot the x-axis separately and use line to align it with the 0 coordinate.
loc <- hist(x, xaxt="n",bty="l")
axis(1, at=loc$breaks,line=-.75)
I think the easiest way to do this is simply to draw it using box, since plot.histogram skips much of the plotting setup that would allow you to pass the appropriate par settings directly:
x<-rnorm(2000, 0, 30)
hist(x)
box(bty = "l")
See the section in par on bty for the possible options.
You can specify xlim and ylim in hist.
Check
?hist
AND
hist(x, xlim = c(-100, 100), ylim = c(0, 500))
I used this code to make this plot:
plot(p, cv2,col=rgb(0,100,0,50,maxColorValue=255),pch=16,
panel.last=abline(h=67,v=1.89, lty=1,lwd=3))
My plot looks like this:
1.) How can I plot the value of the ablines in a simple plot?
2.) How can I scale my plot so that both lines appear in the middle?
to change scale of plot so lines are in the middle change the axes i.e.
x<-1:10
y<-1:10
plot(x,y)
abline(a=1,b=0,v=1)
changed to:
x<-1:10
y<-1:10
plot(x,y,xlim=c(-30,30))
abline(a=1,b=0,v=1)
by "value" I am assuming you mean where the line cuts the x-axis? Something like text? i.e.:
text((0), min(y), "number", pos=2)
if you want the label on the x axis then try:
abline(a=1,b=0,v=1)
axis(1, at=1,labels=1)
to prevent overlap between labels you could remove the zero i.e.:
plot(x,y,xlim=c(-30,30),yaxt="n")
axis(2, at=c(1.77,5,10,15,20,25))
or before you plot extend the margins and add the labels further from the axis
par(mar = c(6.5, 6.5, 6.5, 6.5))
plot(x,y,xlim=c(-30,30))
abline(a=1,b=0,v=1)
axis(2, at=1.77,labels=1.77,mgp = c(10, 2, 0))
Similar in spirit to the answer proposed by #user1317221, here is my suggestion
# generate some fake points
x <- rnorm(100)
y <- rnorm(100)
# positions of the lines
vert = 0.5
horiz = 1.3
To display the lines at the center of the plot, first compute the horizontal and vertical distances between the data points and the lines, then adjust the limits adequately.
# compute the limits, in order for the lines to be centered
# REM we add a small fraction (here 10%) to leave some empty space,
# available to plot the values inside the frame (useful for one the solutions, see below)
xlim = vert + c(-1.1, 1.1) * max(abs(x-vert))
ylim = horiz + c(-1.1, 1.1) * max(abs(y-horiz))
# do the main plotting
plot(x, y, xlim=xlim, ylim=ylim)
abline(h=horiz, v=vert)
Now, you could plot the 'values of the lines', either on the axes (the lineparameter allows you to control for possible overlapping):
mtext(c(vert, horiz), side=c(1,2))
or alternatively within the plotting frame:
text(x=vert, y=ylim[1], labels=vert, adj=c(1.1,1), col='blue')
text(x=xlim[1], y=horiz, labels=horiz, adj=c(0.9,-0.1), col='blue')
HTH