How to get the plot region sizes of subplots? - r

plotrgnsize=function() {
m = par('mai')
o = par('omi')
dev.size()-c(
sum(m[c(2, 4)] + o[c(2, 4)])
, sum(m[c(1, 3)] + o[c(1, 3)])
)
}
The above function can return the plot region size when layout() is not called. When layout() is called, plotrgnsize() can not get the plot region size of each subfigure. How to get the subfigure plot region size?
layout(
mat=rbind(
3
, 2
, 1
)
, heights=c(3, 2, 1)
)
EDIT: Here is the sequence of commands to demonstrate the output.
R> plotrgnsize() # after calling plotrgnsize() once before, then dragged the plot window.
[1] 7.805454 5.767547
# ... then run the layout command shown above.
R> plotrgnsize()
[1] 8.227054 6.393147
R> plot(1:10)
R> plotrgnsize()
[1] 8.227054 6.393147
R> plot(1:10)
R> plotrgnsize()
[1] 8.227054 6.393147
R> plot(1:10)
R> plotrgnsize()
[1] 8.227054 6.393147
As you can see plotrgnsize() does not change when each subfigure is plotted. So it can not get the plot region size for each subfigure.

Related

random generator for multiple character vectors

I'm new to R and want to write a code that generates random workouts. I have 4 character vectors that look like this
Compound_movements <- c('Hip thrust', 'Squat', 'Deadlift')
Abduction <- c('cable aduction', 'lying plated aduction')
Upper <- c('good mornings', 'kneeling squat')
Maxiums <- c('smith machine kick backs', 'cable kickbacks', 'single leg hipthrusts' )
G_H_tie_in <- c('stomp downs' )
I want to code that will pick out and then print 1 or 2 exercises from each vector. What are the best functions for this?
sample is what I think you need.
set.seed(42) # R-4.0.2
sample(Compound_movements, size = 1)
# [1] "Hip thrust"
sample(Compound_movements, size = 1)
# [1] "Hip thrust"
sample(Compound_movements, size = 1)
# [1] "Hip thrust"
sample(Compound_movements, size = 1)
# [1] "Hip thrust"
sample(Compound_movements, size = 1)
# [1] "Squat"
(Yes, apparently you'll do hip thrusts four times in a row ... random is random.)
If those are stored in a list of exercises, you can pick one from each with:
lst_of_exercises <- list(
Compound_movements = c('Hip thrust', 'Squat', 'Deadlift'),
Abduction = c('cable aduction', 'lying plated aduction'),
Upper = c('good mornings', 'kneeling squat'),
Maxiums = c('smith machine kick backs', 'cable kickbacks', 'single leg hipthrusts' ),
G_H_tie_in = c('stomp downs' )
)
sapply(lst_of_exercises, sample, size = 1)
# Compound_movements Abduction Upper Maxiums G_H_tie_in
# "Squat" "lying plated aduction" "good mornings" "single leg hipthrusts" "stomp downs"
And if you need to do other than the same number for all (e.g., 2 of one group, 1 of the others), then perhaps
Map(sample, lst_of_exercises, size = c(1,1,1,2,1))
# $Compound_movements
# [1] "Deadlift"
# $Abduction
# [1] "lying plated aduction"
# $Upper
# [1] "good mornings"
# $Maxiums
# [1] "smith machine kick backs" "cable kickbacks"
# $G_H_tie_in
# [1] "stomp downs"

All data is lost when using sf::st_cast

In the code below I first create a rectangle from two horizontal lines and two vertical lines. Then I use st_polygonize to create a polygon. Finally, I use st_cast to create an object of class,
[1] "XY" "POLYGON" "sfg"
which is what I require. However, when I try to do something similar with a wave it fails. I create the wave polygon by duplicating a wave line, moving it up, and adding sides.
wave_gc plots OK but when I execute:
wave_poly <- class(st_cast(wave_gc, "POLYGON"))
wave_poly is empty. Why is this? How do I end up with an object of class
[1] "XY" "POLYGON" "sfg"
that works?
library(sf)
library(transformr)
# Rectangle #########################
# two vertical lines
v_lines <- st_multilinestring(list(rbind(c(0,0),c(0,1)), rbind(c(3,0),c(3,1))))
# two horizontal lines
h_lines <- st_multilinestring(list(rbind(c(0,0),c(3,0)), rbind(c(0,1),c(3,1))))
all_lines <- c(v_lines, h_lines)
rect_gc <- st_polygonize(all_lines)
rect_poly <- st_cast(rect_gc, "POLYGON")
class(rect_gc)
# [1] "XY" "GEOMETRYCOLLECTION" "sfg"
class(rect_poly)
# [1] "XY" "POLYGON" "sfg"
rect_poly
#################################################################
# Wave
################################################################
w1 <- path_waves(st = TRUE)[[1]]
w2 <- w1
# Add to second column, y values
w2[,2] <- w2[,2] + 0.1
# Vertical bars
nr <- nrow(w1)
v_bars <- st_multilinestring(list(rbind(c(w1[1, 1], w1[1, 2]), c(w2[1, 1], w2[1, 2])),
rbind(c(w1[nr, 1], w1[nr, 2]), c(w2[nr, 1], w2[nr, 2]))))
two_waves <- st_multilinestring(list(w1, w2))
full_wave <- c(v_bars, two_waves)
wave_gc = st_polygonize(full_wave)
wave_poly <- class(st_cast(wave_gc, "POLYGON"))
class(wave_gc)
# [1] "XY" "GEOMETRYCOLLECTION" "sfg"
plot(wave_gc)
wave_poly
# [1] "XY" "POLYGON" "sfg"

How can I change the colors of the slices in pie charts in plotly for r using hexadecimal strings?

This is my pie chart as of right now:
library(plotly)
library(RColorBrewer)
P <- data.frame (labels = c("A", "B", "C", "D", "E"),
values = c(5, 8, 3, 4, 9))
plot_ly(P, labels = labels, values = values, type = "pie",
marker = list(colors=c("lightskyblue", "deepblue", "dodgerblue", "midnightblue", "powderblue")),
textinfo="value",
textposition="outside")
I wanted to change its colors with hexidecimal strings so I could use palettes from RColorBrewer. Thank you in advance!
Just put the hex values into the strings, preceded with a hash (pound symbol) #. the first two digits in hex are for red, the next 2 for green, then 2 digits for blue (#RRGGBB). Optionally you can add an extra two digits for the alpha (transparency) (#RRGGBBAA).
e.g
plot_ly(P, labels = labels, values = values, type = "pie",
marker = list(colors=c("#556677", "#AA3344", "#772200",
"#11AA22", "#AA231B88")), # the last color has alpha value set.
textinfo="value",
textposition="outside")
Exploring RColorBrewer package
library(RColorBrewer)
To see list of functions inside RColorBrewer package
ls("package:RColorBrewer")
# [1] "brewer.pal" "brewer.pal.info" "display.brewer.all"
# [4] "display.brewer.pal"
To display all color schemes
display.brewer.all()
To get the Blues hexadecimal strings
brewer.pal(9,"Blues")
# [1] "#F7FBFF" "#DEEBF7" "#C6DBEF" "#9ECAE1" "#6BAED6" "#4292C6" "#2171B5"
# [8] "#08519C" "#08306B"
brewer.pal(10,"Blues")
# [1] "#F7FBFF" "#DEEBF7" "#C6DBEF" "#9ECAE1" "#6BAED6" "#4292C6" "#2171B5"
# [8] "#08519C" "#08306B"
# Warning message:
# In brewer.pal(10, "Blues") :
# n too large, allowed maximum for palette Blues is 9
# Returning the palette you asked for with that many colors
To View the Blues palatte
display.brewer.pal(9,"Blues")
There are limits on the number of colours you can get, but if you want to extend the Sequential or Diverging groups you can do so with the colorRampPalatte command, for example :
colorRampPalette(brewer.pal(9,”Blues”))(100)
Example for divergent, qualitative and sequential schemes. The Spectral, Set2 , Reds, these names can be seen using command mentioned above display.brewer.all(). You can use some other schemes from the list.
display.brewer.pal(4,"Spectral")
brewer.pal(4,"Spectral")
# [1] "#D7191C" "#FDAE61" "#ABDDA4" "#2B83BA"
display.brewer.pal(4,"Set2")
brewer.pal(4,"Set2")
# [1] "#66C2A5" "#FC8D62" "#8DA0CB" "#E78AC3"
display.brewer.pal(4,"Reds")
brewer.pal(4,"Reds")
# [1] "#FEE5D9" "#FCAE91" "#FB6A4A" "#CB181D"

Display hex codes for colours ggplot2 is using

how can I see what colors ggplot2 is using for discrete categories using a given palette, like "Set1" or "Set2" for brewer? i.e. for a given set of categories what the colors that will be used are?
By default it will use hue_pal with certain defaults. When you use scale_x_brewer it will use brewer_pal with certain defaults (both from the scales package). You'll get as many colors from those palettes as you have categories. e.g. (using the defaults):
f <- hue_pal(h = c(0, 360) + 15, c = 100, l = 65, h.start = 0, direction = 1)
f(3)
## [1] "#F8766D" "#00BA38" "#619CFF"
f(9)
## [1] "#F8766D" "#D39200" "#93AA00" "#00BA38" "#00C19F" "#00B9E3" "#619CFF" "#DB72FB"
## [9] "#FF61C3"
g <- brewer_pal(type="seq", palette=1)
g(3)
## [1] "#DEEBF7" "#9ECAE1" "#3182BD"
g(9)
## [1] "#F7FBFF" "#DEEBF7" "#C6DBEF" "#9ECAE1" "#6BAED6" "#4292C6" "#2171B5" "#08519C"
## [9] "#08306B"
You can see what brewer_palwill do with Set3 or any other named palette by using that as the palette parameter.

Change scaling of data on the x-axis

I am having plot my data like that:
(dput(sale))
structure(c(-0.049668136, 0.023675638, -0.032249731, -0.071487224,
-0.034017265, -0.031278933, -0.052070721, -0.034305542, -0.019041209,
-0.050459175, -0.017315808, -0.012787003, -0.03341208, -0.045078144,
-0.036638132, -0.036533367, -0.012683656, -0.014388251, -0.006775188,
-0.037153807, -0.008941402, -0.011760677, -0.005077979, -0.041187417,
-0.001966554, -0.028822067, 0.021828558, 0.016208791, -0.026897492,
-0.032107207, -0.008496522, -0.028027096, -0.013746662, -0.004545603,
-0.005679941, -0.004614187, 0.004083014, -0.012624954, -0.016362079,
-0.006350167, -0.019551277), na.action = structure(42:45, class = "omit"))
[1] -0.049668136 0.023675638 -0.032249731 -0.071487224 -0.034017265
[6] -0.031278933 -0.052070721 -0.034305542 -0.019041209 -0.050459175
[11] -0.017315808 -0.012787003 -0.033412080 -0.045078144 -0.036638132
[16] -0.036533367 -0.012683656 -0.014388251 -0.006775188 -0.037153807
[21] -0.008941402 -0.011760677 -0.005077979 -0.041187417 -0.001966554
[26] -0.028822067 0.021828558 0.016208791 -0.026897492 -0.032107207
[31] -0.008496522 -0.028027096 -0.013746662 -0.004545603 -0.005679941
[36] -0.004614187 0.004083014 -0.012624954 -0.016362079 -0.006350167
[41] -0.019551277
attr(,"na.action")
[1] 42 43 44 45
attr(,"class")
[1] "omit"
(dput(purchase))
structure(c(0.042141187, 0.075875128, 0.090953485, 0.050951625,
0.082566915, 0.184396833, 0.136625887, 0.042725409, 0.135028692,
0.13201904, 0.093634104, 0.16776844, 0.13645719, 0.201365036,
0.227589832, 0.236473792, 0.269064385, 0.200981722, 0.144739536,
0.145256493, 0.040205545, 0.031577107, 0.014767345, 0.005843065,
0.034805051, 0.082493053, 0.010572227, 0.000645763, 0.033368236,
0.024326153, 0.038601182, 0.025446045, 0.000556418, 0.017201608,
0.008316872, 0.059722053, 0.059695415, 0.076940829, 0.067650014,
0.002029566, 0.008466334), na.action = structure(42:45, class = "omit"))
[1] 0.042141187 0.075875128 0.090953485 0.050951625 0.082566915 0.184396833
[7] 0.136625887 0.042725409 0.135028692 0.132019040 0.093634104 0.167768440
[13] 0.136457190 0.201365036 0.227589832 0.236473792 0.269064385 0.200981722
[19] 0.144739536 0.145256493 0.040205545 0.031577107 0.014767345 0.005843065
[25] 0.034805051 0.082493053 0.010572227 0.000645763 0.033368236 0.024326153
[31] 0.038601182 0.025446045 0.000556418 0.017201608 0.008316872 0.059722053
[37] 0.059695415 0.076940829 0.067650014 0.002029566 0.008466334
attr(,"na.action")
[1] 42 43 44 45
attr(,"class")
[1] "omit"
timeLine <- c(-20 , +20)
plot(sale,type="b", xlim=timeLine, ylim=c(-.1,.4) )
lines( purchase, type="b")
abline(v=0, col="black")
The plot I get looks like that:
Whats wrong with the plot is the scaling. My graphs should start at -20 and should got to +20 whereas each data point like -20, -19, -18, ..., +19, +20 is a point in the graph. In my exported csv sheet I have a row with these values. My question is, how to start from -20 so that every data point is an integer number to +20? Is is also possible to display every integer from -20 to +20?
I really appreciate your answer!
UPDATE
The scaling of the axis:
By, default the values are plotted against their index (starting at 1) when x is not specified in plot. You have to create a vector for the x axis.
timeLine <- c(-20 , 20)
# this command generates a sequence from -20 to 20
timeSeq <- Reduce(seq, timeLine)
# now, this sequence is passed to `x`
plot(sale, x = timeSeq, type = "b", xlim = timeLine, ylim = c(-.1, .4) )
lines(purchase, x = timeSeq, type = "b")
abline(v = 0, col = "black")
Update: how to show all x axis labels?
You can show all x axis labels if you decrease their size (cex.axis) and increase the width of the plot. Here's an example.
png("plot.png", width = 1000)
plot(sale,type="b", x = timeSeq, xlim=timeLine, ylim=c(-.1,.4),
xaxt = "n")
lines( purchase, type="b", x = timeSeq)
abline(v=0, col="black")
axis(side = 1, at = timeSeq, cex.axis = 0.75)
dev.off()

Resources