I want to present percentages over a 24h period in 15 min intervals as a bar plot.
When I use barplot(), the labels for those timepoints are more or less randomly chosen by R (depending on how I format the window. I know it's not random, but it's not what I want either). I would rather have them evenly spaced at 1 h intervals (that is every 4th bar).
I have searched extensively on this and know i can add labels later with axis() but I have not found a way to set which bars are labeled and which are left blank.
So here is an example. Sorry for the long lines:
x<-sample(1:100,96)
Labels<-c("09","09:15","09:30","09:45","10:00","10:15","10:30","10:45","11","11:15","11:30","11:45","12","12:15","12:30","12:45","13","13:15","13:30","13:45","14","14:15","14:30","14:45","15","15:15","15:30","15:45","16","16:15","16:30","16:45","17","17:15","17:30","17:45","18","18:15","18:30","18:45","19","19:15","19:30","19:45","20","20:15","20:30","20:45","21","21:15","21:30","21:45","22","22:15","22:30","22:45","23","23:15","23:30","23:45","00","00:15","00:30","00:45","01","01:15","01:30","01:45","02","02:15","02:30","02:45","03","03:15","03:30","03:45","04","04:15","04:30","04:45","05","05:15","05:30","05:45","06","06:15","06:30","06:45","07","07:15","07:30","07:45","08","08:15","08:30","08:45")
names(x)<-Labels
barplot(x)
I do not think you can force R to show every label if it does not have enough space. But at least if you want to add the labels every 1h, the following code should work :
x<-sample(1:100,96)
Labels<-c("09","09:15","09:30","09:45","10","10:15","10:30","10:45","11","11:15","11:30","11:45","12","12:15","12:30","12:45","13","13:15","13:30","13:45","14","14:15","14:30","14:45","15","15:15","15:30","15:45","16","16:15","16:30","16:45","17","17:15","17:30","17:45","18","18:15","18:30","18:45","19","19:15","19:30","19:45","20","20:15","20:30","20:45","21","21:15","21:30","21:45","22","22:15","22:30","22:45","23","23:15","23:30","23:45","00","00:15","00:30","00:45","01","01:15","01:30","01:45","02","02:15","02:30","02:45","03","03:15","03:30","03:45","04","04:15","04:30","04:45","05","05:15","05:30","05:45","06","06:15","06:30","06:45","07","07:15","07:30","07:45","08","08:15","08:30","08:45")
b=barplot(x,axes = F)
axis(2)
axis(1,at=c(b[seq(1,length(Labels),4)],b[length(b)]+diff(b)[1]),labels = c(Labels[seq(1,length(Labels),4)],"09"))
Related
I have some discrete data that I'm trying to plot in a histogram in R. I'm using the built in hist() function, which works fine most of the times for the data I have. However, when it comes to a discrete variable it looks somewhat strange (unfortunately I cannot add the picture). I interpret it as "since the bin for 0 and 1 children must fit between 0 and 1 it determines the width of all bins and thus the "from 1.5 to 2" result". How can I put the numbers on the x-axis centered underneath each bin instead?
Thanks in advance!
You might want to consider drawing the axis in a second step:
Prevent x-axis with xaxt="n":
hist(cars$speed, xaxt="n")
Draw x-axis and adjust label position with hadj=:
axis(1, at=seq(0,25,5), hadj=2.5, labels = c("",seq(5,25,5)))
Data Background: I have a large data frame (50,000 values, 10,000 when removing NAs) for a single chromosome. I am trying to plot a fixation index (Y-range: 0-1)(data$'N:S') across chromosomal positions (X-range: 0-250,000,000)(data$'pos'). I used a program (popoolation 2) to calculate sliding window averages for a window size of 50,000 and a step size of 10,000, resulting in my data. However, on R this is too noisy and it comes out looking like a blob. When I zoom in by changing the x-axis so each tick is 500,000 separation, you can see the trends nicely. I think I can fix this on a large chromosomal stage by increasing the area of the x-axis and finding a way to simplify the data.
Currently I have: All my data plotted, simple mean, StandDevs (color coded)
I am trying to figure out two things.
1 Is there a way to extend the X-axis to stretch out the length of it. I don't want to change the markers on it or what it displays, I want to make the actual length longer. (Example, if I had a graph on a piece of paper that showed an x-Axis of 1-10 on a 2" area, I would want to increase the area to 5", not change the defined limits to say 1-100. so, not xlim function)
2 Simplify the data in some way. I was thinking easiest would be a smoothed or rolling mean across the data. When I use rollmean() or smooth() it separates my data from the x-axis, so it only extends to the 8,000 points and when I plot it doesn't go across the whole chromosomal graph with the rest of my data. Someone mentioned there may be away to instead randomly sample data to simplify it?
2B If I get a trendline to work, can I color code it so that part of it that is 1 or 2 standard deviations above the mean can be a different color if I mute my actual background data and remove its color.
R Code
Image 1-Plotting All Positions
plot(data$'Pos',data$'N:S', ylim=c(0,0.5), col=data$Colour)
Image 3-I tried both
lines(smooth(datatest$`N:S`), type="l", col = "blue", lwd = 1)
and
rolling = rollmean(datatest$N:S, 9)
lines(rolling, type="b", col = "purple", lwd = 1)
Image 2-Plotting a Nice Subsection-- why I want to extend X-axis
plot(data$'Pos',data$'N:S', ylim=c(0,0.5), xlim=c(163000000,165000000), col=data$Colour)
Notes:
If it matters, my graph has colored points due to color coded regions related to means and Standard Dev.
data$Colour[data$'N:S'>=data_SD1above]="orange"
Also, the only difference between data and datatest was that datatest had NA values removed.
Image 1: All Positions-Messy
Image 2: Zoomed In to see trends
Image 3: All positions with the two attempted trendlines
So it seems like that you want to resize the width of the graph for the visualization.
if you use Rstudio, there is an output option which changes the width and height of the graph.
if you use the console, you can save your plot with width and height. for example
png("mychromosome.png".width=1000,height=300)
plot(..blah..blah..)
dev.off()
I hope it will help you.
I am trying to have R shiny print out the sample information when hovering over a data point in a ggplot2 geom_point plot. The axes for my plot have 4 decimal points but if I print plot_hover$x and $y it only returns two decimal points, so the output ends up being the same for every point on the plot. I noticed the examples on the shiny site also only output two decimal points. Is there a way to change this to retain more information in input$plot_hover?
Without a reproduceable example this is tough, so all of these are complete guesses as to what your actual problem is. Here are some stabs in the dark as to how to fix a problem where ggplot is not printing enough digits.
#HubertL: You may be able to control the number of printed digits using
options(digits = 10)
Or use a wrapper around any calculations to specify the number of rounded digits to include in a calculation or output from a function
round(calculation, 10)
Additionally, this could be an issue with the space on the plot axis. You may want to try decreasing the size of the text on the axis within the plot using
plot + theme(axis.text.x = element_text(size = 8))
And you could add angle in there as well to rotate the numbers to validate there is enough space.
I had some problems while trying to plot a histogram to show the frequency of every value while plotting the value as well. For example, suppose I use the following code:
x <- sample(1:10,1000,replace=T)
hist(x,label=TRUE)
The result is a plot with labels over the bar, but merging the frequencies of 1 and 2 in a single bar.
Apart from separate this bar in two others for 1 and 2, I also need to put the values under each bar.
For example, with the code above I would have the number 10 under the tick at the right margin of its bar, and I needed to plot the values right under the bars.
Is there any way to do both in a single histogram with hist function?
Thanks in advance!
Calling hist silently returns information you can use to modify the plot. You can pull out the midpoints and the heights and use that information to put the labels where you want them. You can use the pos argument in text to specify where the label should be in relation to the point (thanks #rawr)
x <- sample(1:10,1000,replace=T)
## Histogram
info <- hist(x, breaks = 0:10)
with(info, text(mids, counts, labels=counts, pos=1))
this is a follow up to a previously asked, related question:
data and code are here error message when ploting subjects at risk with survplot
When trying to plot the subjects at risk below the survplot, the table either overlaps with the labels of the x - axis or does not appear on the plot (in the example below one line is missing; totalps=4). How to solve this issue?
From the documentation to the survplot command, I understand that I may have to reset the margins of the plot with the par command (e.g. par(mar=c(5,4,4,2)+.1).) I don't understand how to include this par command into survplot.
Furthermore, there is considerable space between the lines of the table on the subjects at risk. Is there any direct way to reduce this space?
Here the code for the plot:
library(rms)
pdf(plot1.pdf)
survplot(KM.Duration.totalps[-1],
xlab="duration in months", ylab="survival prob",
conf="none",
label.curves=list(method="arrow", cex=0.8),
time.inc=12,
col=c(1:4),
levels.only = FALSE,
n.risk=TRUE,
y.n.risk = -0.3, cex.n.risk = 0.6
)
dev.off()
Simply reading the help page:
sep.n.risk
multiple of upper y limit - lower y limit for separating lines of text containing number of subjects at risk. Default is .056*(ylim[2]-ylim[1]).
And some par functions are best used with par just prior to the plot call (but after the pdf() call), so:
pdf(...)
par( mar=c(7,4,4,2)+.1) ) # adds two lines to default space along bottom margin
survplot(...
You set the margins before you plot, like so:
par(mar=(0,0,0,0))
plot(c(1:10))
will give you a plot with no margins. par(mar=(1,2,3,4) will give you a margin of one text line at the bottom, two on the left, three on the top, and four on the right.
If you want to specify the margins in inches use par(mai=(x,x,x,x)). The default for R is that an output device is 7 by 7 inches, although depending on the device (including ones I've written), that might be a little fuzzy.