Barplot labels too long, is it possible to set a "label width" - r

I am trying to create a stacked barplot where beside = TRUE. Here is the data used to generate this figure;
significant <- c(27, 44, 25, 54, 40, 31, 25, 9, 57, 59)
annotated <- c(119, 267, 109, 373, 250, 173, 124, 20, 452, 478)
names <- c("mitochondrial gene expression","ncRNA metabolic process",
"mitochondrial translation", "translation",
"ribonucleoprotein complex biogenesis", "ribosome biogenesis",
"rRNA metabolic process", "transcription preinitiation complex asse...",
"peptide biosynthetic process", "amide biosynthetic process")
data = rbind(significant, annotated)
colnames(data) <- names
rownames(data) <- c("significant", "annotated")
My plotting code is;
printBarPlots <- function(input, main){
data = rbind(input[,4], input[,3])
colnames(data)= input[,2]
rownames(data)=c("Significant", "Annotated")
par(mar=c(5,9,4,2))
mybar = barplot(data, width = 3, xlab = "Number of genes", main = main,
horiz = T, cex.axis = 0.8, beside = TRUE, las = 1,
cex.names = 0.8, legend = T, args.legend = list(x="right"))
}
Using this code, the bar labels extend far to the left of my plot. My question is unlike this questionbecause splitting the bar names at each space would still require having to have a small cex.names. Is it possible to specify that rather than having something like "transcription preinitiation complex asse..." written on one line, it can be spread out over two lines, such as below, to make better use of space? Or perhaps, some sort of code to split names onto different lines following a certain amount of letters (e.g. start new line after 13 characters).
"transcription preinitiation
complex asse..."

Related

Display grouped percentages in Likert plot with Plotly R

I have a dataframe like this:
library(tidyverse)
data <- tibble(Question_num = rep(c("Question_1", "Question_2"),each= 5),
Answer = rep(c('Strongly disagree',
'Disagree',
'Neutral',
'Agree',
'Strongly agree'), 2),
n = c(792, 79, 69, 46, 24, 34, 34, 111, 229, 602),
prop = c(78.4, 7.82, 6.83, 4.55, 2.38, 3.37, 3.37, 11.0, 22.7, 59.6))
where:
Question_num is the label of a question;
Answer is the response mode;
n is a simple count for each response mode;
prop is proportion, in percentage;
I would like to represent it graphically through a dynamic bar graph with divergent colours. Perhaps, this would be a starting point:
library(plotly)
library(RcolorBrewer)
data %>%
plot_ly(x = ~prop,
y = ~Question_num,
color = ~Answer) %>%
add_bars(colors = "RdYlBu") %>%
layout(barmode = "stack")
Is it possible, with Plotly in R, to obtain an ordered plot, which has the neutral category clearly delineated (in the center) and the percentages summarised by grouping the extreme categories together (even if they are in their plotted in different colours)? What I would like to obtain is a plot similar to this one:
The plot in the picture is obtained from a dataset in a different format (wide, not long) and with the likert package, which computes everything automatically. Could such a result be achieved with plotly (both for percentages and for counts)? If so, how?
I could not find any documentation to answer this challenging question.
Thank you very much to those who can help me.
The following isn't addressing all of the issues your post is raising (It might be better to split this into multiple questions).
However, I'd like to share what I was able to get so far.
(Sorry for switching from tidyverse to data.table - I'm not familar with the tidyverse and I'm not planning to familiarize any time soon).
To get the desired plot we can switch to barmode = 'relative'
Run schema() and navigate:
object ► traces ► bar ► layoutAttributes ► barmode
Determines how bars at the same location coordinate are displayed on
the graph. With stack, the bars are stacked on top of one another.
With
relative, the bars are stacked on top of one another, with negative values below the axis, positive values above
library(data.table)
library(plotly)
DF <- data.frame(Question_num = rep(c("Question_1", "Question_2"),each= 5),
Answer = rep(c('E - Strongly disagree',
'D - Disagree',
'A - Neutral',
'B - Agree',
'C - Strongly agree'), 2),
n = c(792, 79, 69, 46, 24, 34, 34, 111, 229, 602),
prop = c(78.4, 7.82, 6.83, 4.55, 2.38, 3.37, 3.37, 11.0, 22.7, 59.6))
DT <- as.data.table(DF)
DT[, order := .GRP, by = Answer]
DT[Answer == "A - Neutral", c("n", "prop") := .(n/2, prop/2)][Answer %in% c("E - Strongly disagree", "D - Disagree"), prop := -prop]
DT <- rbindlist(list(DT, DT[Answer == "A - Neutral", .(Question_num = Question_num, Answer = Answer, n = n, prop = -prop, order = order-0.5)]))
setorder(DT, -Question_num, order)
# setorder(DT, order)
fig <- plot_ly(
data = DT,
type = "bar",
x = ~ prop,
y = ~ Question_num,
color = ~ Answer,
colors = c("E - Strongly disagree" = "#a6611a",
"D - Disagree" = "#d2b08c",
"A - Neutral" = "#b3b3b3",
"B - Agree" = "#80c2b8",
"C - Strongly agree" = "#018571"),
text = ~ paste0(prop, "%"),
textfont = list(
size = 12,
color = 'black')
)
fig <- layout(
fig,
barmode = "relative",
xaxis = list(title ="Percentage"),
yaxis = list(
categoryorder = "array",
categoryarray = sort(unique(DT$Question_num), decreasing = TRUE),
title = ""
),
legend = list(orientation = "h")
)
print(fig)
Here a related question can be found.

a single ColorRamp palette yields different color schemes in two plotly scatterplots

As the title says, a single ColorRamp palette when used in two different scetterplots built by plotly, gives two slightly differently looking (note the middle part) colorbars even though the upper and the lower bounds of corresponding data sets are manually set to be identical in both plots.
I'd like to make the plots visually comparable, and for that I'd obviously have to have identical colorbars. Is there a way to do that?
Here's the code:
myxaxis <- list(range = c(16, 44), dtick=2, gridwidth = 1, title = "Length of carbon chain") #setting the visible area of x axis
myyaxis <- list(range = c(0, 8), gridwidth = 1, title = "No. of double bonds") #setting the visible area of y axis
mycolors <- colorRampPalette(c('green', 'red', 'black'))(n = 100) #creating an RColorBrewer palette
ch_new1 <- cbind.data.frame(c('PA', 'PA', 'PA', 'PA', 'PA', 'PA', 'PA', 'PA', 'PA', 'upper bound', 'lower bound'), c(4.571087, 6.522441, 6.522441, 5.081869, 4.471815, 5.744834, 7.329796, 5.472866, 5.744834, 1, 1), c(10.52337, 16.75454, 16.0976, 16.47356, 18.94973, 17.46351, 10.97607, 18.11186, 11.64033, 0.2085327, 71.18021), c(32, 34, 34, 36, 36, 36, 38, 38, 38, 100, 100), c(1, 1, 2, 2, 3, 4, 4, 5, 6, 100, 100), c(0.4128963, 16.68394, 26.52718, 23.50851, 16.02339, 3.971546, 6.854153, 3.24342, 2.774968, 1, 1)) #the first dataset
colnames(ch_new1) <- c('Species', 'log_inversed_pval','fold_difference', 'N_of_carbons','N_of_double_bonds', 'rel_abund')
d <- plot_ly(ch_new1, x=~N_of_carbons, y=~N_of_double_bonds, text = ~paste('Percent of total', Species, '=', round(rel_abund, 0)), size=~rel_abund, color=~fold_difference, colors = mycolors)%>% #producing the scatter plot
layout(
xaxis = myxaxis,
yaxis = myyaxis,
title = paste('PA', '2b')
)%>%
colorbar(title="Fold difference", ypad=20)
export(d)
ch_new2 <- cbind.data.frame(c('LPC', 'LPC', 'LPC', 'lower limit', 'upper limit'), c(7.329796, 7.329796, 5.081869, 1, 1), c(2.952345, 5.042931, 3.700331, 0.2085327, 71.18021), c(18, 20, 22, 100, 100), c(0, 3, 5, 100, 100), c(82.87528, 13.56943, 3.555281, 1, 1)) #the second dataset
colnames(ch_new2) <- c('Species', 'log_inversed_pval','fold_difference', 'N_of_carbons','N_of_double_bonds', 'rel_abund')
d <- plot_ly(ch_new2, x=~N_of_carbons, y=~N_of_double_bonds, text = ~paste('Percent of total', Species, '=', round(rel_abund, 0)), size=~rel_abund, color=~fold_difference, colors = mycolors)%>% #creating the second scatterplot
layout(
xaxis = myxaxis,
yaxis = myyaxis,
title = paste(unique(ch$Species)[i], fraction)
)%>%
colorbar(title="Fold difference", ypad=20)
export(d)
chart #1 with bright red middle
chart #2 with dim red middle
I've solved the problem on my own.
Turns out that by adding one or several "anchoring" dummy points placed beyond the margins of the plot (so they are not shown) helps to make the plot colorbars almost identical.
The initial dataset
ch_new1 <- cbind.data.frame(c(...)) #the first dataset
should be appended with anchoring dummy points:
ch_new1 <- cbind.data.frame(c(...)) #the first dataset
ch_new1 <- rbind(ch_new, list('middle anchor point', 1, 50, 100, 100, 1))
ch_new1 <- rbind(ch_new, list('quarter anchor point', 1, 25, 100, 100, 1))
tl;dr anchor the variable responsible for colorbar to multiple reference points (10, 20, 30, 40, 50, ...)

use sm.density.compare to plot density functions, draw lines for each mode and get the mode values back

I have got dive depth data for seabirds over several trips and I would like to find the modes for each trip, plot the density functions and a line corresponding to the modes. So far, here's the code I have been using:
maxdepths<-read.csv("maximum_depths.csv", header=T)
maxdepths_ind21<-maxdepths[maxdepths$bird=="21",]
# create value labels
trip.f <- factor(maxdepths_ind21$trip, levels= c(21.1,21.2,21.3,21.4,21.5,21.6,21.7,21.8),
labels = c("Trip1", "Trip2", "Trip3", "Trip4", "Trip5", "Trip6", "Trip7", "Trip8"))
# plot densities
z<-sm.density.compare(maxdepths_ind21$maxdep, maxdepths_ind21$trip,model="equal")
sm.density.compare(maxdepths_ind21$maxdep, maxdepths_ind21$trip, xlab="Maximum depth (m)", xlim=c(0, 90), axes=F)
title(main="Maximum dive depth by trip, individu 21")
axis(side = 1, at = c(0,5,10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90))
axis(side = 2, at = c(0,0.01,0.02,0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09, 1))
# add legend via mouse click
colfill<-c(2:(2+length(levels(trip.f))))
legend(locator(1), levels(trip.f), fill=colfill)
The result looks good, ie I've got one curve per trip with different colours/line types per trip.
I now would like to draw lines for each trip when the density functions are maximized, as well as find those values. I am aware of this thread
R: getting data (instead of plot) back from sm.density.compare
and I have tried assigning the result of sm.density.compare to an object and then calling it, like so:
z<-sm.density.compare(maxdepths_ind21$maxdep, maxdepths_ind21$trip,model="equal")
z
I was looking for the values of the modes within this output but I got confused by all the values that are returned.
Any help would be much appreciated!
TIA

Mixed text-justification or tabstops in legends in R

I want a legend like this:
I created this with five (sic!) legend()s, placing them side-by-side. Here is a working code sample (without colors):
plot(1, 0, xlim=c(1,11), ylim=c(0,45))
legend(0.6, 46.75, c("KVT", "", "", "IPT", "", ""), pch = c(0, 1, 2), bty = "n")
legend(1.4, 46.75, c(expression(paste("t1: ", italic(M), " =")), "t3:", "t5:", "t1:", "t3:", "t5:"), bty = "n")
legend(3.35, 46.75, c(19.31, 9.91, 10.79, 19.36, 9.69, 2.82), bty = "n", adj = 1)
legend(3.6, 46.75, "n = ", bty = "n")
legend(4.7, 46.75, c(213, 208, 61, 186, 159, 11), bty = "n", adj = 1)
This works, as you can see, but I need to loop through several variables, with different means and scales (here: 0 to 45), and I don't want to manually adjust the placement of five legends each time.
How can I create a similar legend using only one legend("topleft", ...), employing something similar to tabstops in Word to place the text within each line, or, if that is not possible, automatically placing multiple text boxes similar to a float: left in CSS.
Note that the columns of numbers are right-justified.
I tried with the ncol argument in legend(), but could get neither the partial right-alignment nor the partial suppression of symbols to work.
Your solution need not use the given numbers, symbols or colors. They will only make the code confusing.
To my knowledge there is no way to specify tab stops, but you could use space padding to control alignment. Here is the closest I could get, with 2 caveats
There must be some syntax to make it evaluate italic(M) but, for convenience, I replaced it with the letter "M"
I had to use fidex-width fonts to make sure the spaces align
Here is my proposed solution:
# store components of each row in a separate vector
l1 <- c("KVT", "", "", "IPT", "", "")
l2 <- c("t1: M =", "t3:", "t5:", "t1:", "t3:", "t5:")
l3 <- c(19.31, 9.91, 10.79, 19.36, 9.69, 2.82)
l4 <- c("n =", rep("", 5))
l5 <- c(213, 208, 61, 186, 159, 11)
# merge everything together with suitable space padding
tags <- paste(sprintf("%3s", l1),
sprintf("%-8s", l2),
sprintf("%5s", l3),
sprintf("%-3s", l4),
sprintf("%3s", l5))
plot(1, 0, xlim=c(1,11), ylim=c(0,45))
par(family="mono") ## have to use monotype for spaces to align
legend(0.6, 46.75, tags, pch = c(0, 1, 2), bty = "n")
I hope that helps, even if it's not exactly what you requested.

How do I plot two models into one graph

I used DoseFinds to building the two models and I want to
plot both model on the same graph to compare.
library(DoseFinding)
doses <- c(0, 10, 25, 50, 100, 150)
fmodels <- Mods(emax = 25,
doses=doses, placEff = 0.5, maxEff = -0.4,
addArgs=list(scal=200))
fmodels2 <- Mods(emax = 25,
doses=doses, placEff = -1.5, maxEff = -1.4,
addArgs=list(scal=200))
plot(fmodels)
plot(fmodels2)
Combine the two things into one object:
doses <- c(0, 10, 25, 50, 100, 150)
fmodels2 <- Mods(emax = c(25,25),
doses=doses, placEff = c(0.5,-1.5), maxEff = c(-0.4,-1.4),
addArgs=list(scal=200))
then plot with superpose=TRUE:
plot(fmodels2, superpose=TRUE)
The two lines don't overlap much so although it looks like two separate graphs, it isnt!
I guess you want to use superpose = TRUE when you call the plot-function (?plot.Mods). This will plot the models in the same graph if they are in the same Mods-object. See ?Mods for how to have more than one model in the same object.

Resources