I've created the stacked bar chart below. I would like to remove the white border line between the two colors of the bar. Is this possible?
counts<- structure(list(
A = c(51,11),
B = c(51,11),
C = c(31,9),
D = c(46,3),
E = c(20,3),
F = c(57,29),
G = c(31,6),
H = c(6,0)),
.Names = c("I'm sure of myself when I do science activities",
"I would consider a career in science",
"I expect to use science when I get out of school",
"Knowing science will help me earn a living",
"I will need science for my future work",
"I know I can do well in science",
"Science will be important to me in my life’s work",
"I cannot do a good job with science"
),
class = "data.frame",
row.names = c(NA, -2L)) #4L=number of numbers in each letter vector#
attach(counts)
print(counts)
# barplot
colors <- c("slategray3","dodgerblue4")
counts <- counts[, order(colSums(counts))]
xFun <- function(x) x/2 + c(0, cumsum(x)[-length(x)])
par(mar=c(2, 22, 4, 2) + 0.1) # this sets margins to allow long labels
byc <- barplot(as.matrix(counts), horiz=TRUE, col=colors, #main="N=35"#,
border=FALSE, las=1, xaxt='n',
ylim = range(0, 12), xlim = range(-10, 100),
width = 1.35)
# labels
labs <- data.frame(x=as.vector(sapply(counts, xFun)), # apply `xFun` here
y=rep(byc, each=nrow(counts)), # use `byc` here
labels=as.vector(apply(counts, 1:2, paste0, "%")),
stringsAsFactors=FALSE)
labs$labels[labs$labels %in% paste0(0:(8*100)/100, "%")] <- "" #masks labels <8
invisible(sapply(seq(nrow(labs)), function(x) # `invisible` prevents unneeded console
output
text(x=labs[x, 1:2], labels=labs[x, 3], cex=.9, font=2, col=0)))
#adds % to scale
scale <- seq(0, 100, by = 20)
axis(side = 1, at = scale, labels = paste0(scale, "%"), cex.axis = 1)
#this adds gridlines
grid(nx = NULL, ny = nx, col = "lightgray", lty = "dotted",
lwd = par("lwd"), equilogs = TRUE)
# legend (set `xpd=TRUE` to plot beyond margins!)
legend(15,14.5, legend=c("Agree","Strongly Agree"),
fill=colors, horiz = T, bty='n', xpd=T)
You could try: border=NA,
byc <- barplot(as.matrix(counts), horiz=TRUE, col=colors, #main="N=35"#,
border=NA, las=1, xaxt='n',
ylim = range(0, 12), xlim = range(-10, 100),
width = 1.35)
Related
I would like to automate data labels (with % signs) placed on top of the vertical bars produced with the code below. Is there a way to do this?
H <- c(61,89,94,89) # Create the data for the chart.#
M <- c("Pre-Calculus",
"College Algebra",
"Intermediate Algebra",
"Elementary Algebra")
par(mar=c(5.1, 10, 4, 1.1))
barplot(H, col =c("dodgerblue4" ), ylim = range(0,110),
names.arg = M, horiz = F,
family="Arial", border = NA, xlim = range(0,5), las=1,
axes = T, ylab = 'Passing Percent')
Use the text() function. See this SO post for reference
bp <- barplot(H, col =c("dodgerblue4" ), ylim = range(0,110),
names.arg = M, horiz = F,
family="Arial", border = NA, xlim = range(0,5), las=1,
axes = T, ylab = 'Passing Percent')
text(bp, H + 5, paste(H, "%", sep=""))
I am attempting to create several histograms that display the effects a drug has on the frequency of heart attacks.
Currently, R is organizing my data into the bins [0 - 0.5, 0.5 - 1.0, 1.0 - 1.5, etc.], but I would like for it to only use integer values: [0 - 1, 1 - 2, 2 - 3, etc.].
I have tried using the xaxt="n" argument and the axis() function. They "worked," but they did not solve the problem above. I also tried to use breaks=seq(0,5,l=6), but this converted my y-axis from frequency into density.
Here is the code for my latest two attempts:
hist(fourTrials$red_5, breaks=5, right = FALSE,
xlab = "Number of Heart Attacks",
xlim = c(0, 4), ylim = c(0,4),
main = "Experimental Group 1, n = 400", col = "light blue")
hist(fourTrials$red_5, breaks=seq(0,5,l=6), freq = F, right = FALSE,
xlab = "Number of Heart Attacks",
xlim = c(0, 4), ylim = c(0,4),
main = "Experimental Group 1, n = 400", col = "light blue",yaxs="i",xaxs="i")
Thanks for any help!
I believe that what you want is:
hist(fourTrials$red_5, breaks=0:4, freq = TRUE, right = FALSE,
xlab = "Number of Heart Attacks",
xlim = c(0, 4), ylim = c(0,4),
main = "Experimental Group 1, n = 400",
col = "lightblue", yaxs="i", xaxs="i")
I get a problem for setting the position of legend and wonder if anyone can help.
I follow this example:
http://www.thisisthegreenroom.com/2009/choropleths-in-r/
My code is:
require(maps)
require(ggmap)
library(openxlsx)
rm(list = ls())
map("state", "Arizona")
setwd('M:/SCC/Q-Board')
PM25 <- read.xlsx("PM2.5_Emission_AZ_60 EIS emission sectors.xlsx", sheet = 'Emission_County', colNames = TRUE)
colors = c("#F1EEF6", "#D4B9DA", "#C994C7", "#DF65B0", "#DD1C77",
"#980043")
PM25$colorBuckets <- as.numeric(cut(PM25$PM25, c(0, 5, 10, 20, 30,40, 50)))
map("county",'Arizona', col = colors[PM25$colorBuckets], fill = TRUE,boundary = TRUE, resolution = 0,
lty = 1, projection = "polyconic")
title("PM2.5 Emission by county, 2011")
leg.txt <- c("<5", "5-10", "10-20", "20-30", "30-40", ">40")
legend("bottom", leg.txt, horiz = F, fill = colors,bty="n",title = 'Unit:1000 tons')
Then, the output figure was shown in below. I try to change the position by setting "top", "left"....
But the legend are still overlap with the figure.
Thank you for your help !
It seems to me that you simply run of out the plotting region. This is very common for spatial plot, which will often occupy a significant amount of your plotting domain. I would split the domain into two: one for spatial plot, the other for legend. The following code does this:
## a function to set up plotting region
## l: ratio of left region
## r: ratio of right region
split.region <- function(l, r) {
layout(matrix(c(rep(1, l), rep(2, r)), nrow = 1))
mai <- par("mai")
mai[2] <- 0.1
mai[4] <- 0
par(mai = mai)
}
# use 80% region for main image
# use 20% region for legend
split.region(4, 1)
## produce your main plot
image(x = 0:10/10, y = 0:10/10, matrix(rbinom(100, 1, 0.3), 10), bty= "n", xaxt = "n", yaxt = "n", ann = FALSE, main = "sample plot")
## set up 2nd plot, with nothing
plot(1:2, bty="n", ann=FALSE, xaxt = "n", yaxt = "n", col = "white")
## add your legend to your second plot
leg.txt <- c("<5", "5-10", "10-20", "20-30", "30-40", ">40")
## place legend at bottom left
legend("bottomleft", leg.txt, horiz = F, pch = 15, col = 1:6, bty="n", title = 'Unit:1000 tons', cex = 1.5)
Adjust l, r until you are satisfied.
how to
Combine a bar chart and line in single plot in R (from different data sources)?
Say I have two data sources as:
barData<-c(0.1,0.2,0.3,0.4) #In percentage
lineData<-c(100,22,534,52,900)
Note that they may not be in the same scale.
Can I plot both barData and LineData in one plot and make them good looking ?
I cant use ggplot in this case so this is not a duplicated question..
Something like the following:
Maybe this helps as a starting point:
par(mar = rep(4, 4))
barData<-c(0.1,0.2,0.3,0.4) * 100
y <- lineData<-c(100,22,534,900);
x <- barplot(barData,
axes = FALSE,
col = "blue",
xlab = "",
ylab = "",
ylim = c(0, 100) )[, 1]
axis(1, at = x, labels = c("Julia", "Pat", "Max", "Norman"))
ats <- c(seq(0, 100, 15), 100); axis(4, at = ats, labels = paste0(ats, "%"), las = 2)
axis(3, at = x, labels = NA)
par(new = TRUE)
plot(x = x, y = y, type = "b", col = "red", axes = FALSE, xlab = "", ylab = "")
axis(2, at = c(pretty(lineData), max(lineData)), las = 2)
mtext(text="Lines of code by Programmer", side = 3, line = 1)
box()
I want to add labels to the columns of my barplot. Since there are 2 groups each pair of columns will share the same label, i.e 7 labels from "dislike very much" to "like very well".
Since labels titles are quite long I intended to rotate them using the text() function but I cannot get it to display correctly. Here is the code:
A <- c(0, 1, 0, 1, 14, 44, 42)
B <- c(0, 0, 0, 2, 14, 41, 45)
x <- rbind(A, B)
dd.names <- c("Dislike very much", "Strongly dislike", "Dislike", "Neither like nor dislike", "Like", "Like well", "Like very well")
bp <- barplot(x,
beside = TRUE, # Plot the bars beside one another; default is to plot stacked bars
space=c(0.2,0.8), # Amount of space between i) bars within a group, ii) bars between groups
legend = c("Fish cake containing sugar kelp", "Control fish cake"),
args.legend = list(x = "topleft", bty = "n", inset=c(0.1, 0.1)), # bty removes the frame from the legend
xlab = "",
ylab = "Number of scores",
ylim = range(0:50), # Expand the y axis to the value 50
main = "Score results from taste experiments of fish cakes")
text(bp, par("usr")[1], pos = 1, offset = 2, labels = dd.names, adj = 0.5, srt = 25, cex = 0.8, xpd = TRUE)
IMO you're better off rotating the graph.
par(mar=c(3,8,1,1),mgp=c(1.5,.5,0))
bp <- barplot(x,
beside = TRUE,
space=c(0.2,0.8),
legend = c("Fish cake containing sugar kelp", "Control fish cake"),
args.legend = list(x = "bottom", bty = "n", inset=c(0.1, 0.1)),
ylab = "",
xlab = "Number of scores",
xlim = range(0:50), # Expand the y axis to the value 50
main = "Score results from taste experiments of fish cakes",
horiz = TRUE)
text(rep(0,length(dd.names)),bp[1,], par("usr")[3], pos = 2,
labels = dd.names, cex = 0.8, xpd = TRUE)
In an unsolicited act of evangelism, here is a ggplot solution.
library(ggplot2)
library(reshape2) # for melt(...)
library(grid) # for unit(...)
gg <- melt(data.frame(dd.names,t(x)),id="dd.names")
gg$dd.names <- with(gg,factor(dd.names,levels=unique(dd.names)))
ggplot(gg,aes(x=dd.names,y=value))+
geom_bar(aes(fill=variable),stat="identity",position="dodge")+
coord_flip()+
scale_fill_manual(name="",values=c("grey30","grey70"),
labels=c("Fish cake containing sugar kelp", "Control fish cake"))+
labs(title="Score results from taste experiments of fish cakes",
x="",y="Number of scores")+
theme_bw()+theme(legend.position = c(1,0),legend.justification = c(1,0),
legend.key.height=unit(0.8,"lines"))