Plotly: How to set manual zoom for camera view in a 3D plot? - r

I use the data below to create a 3D plot but I cannot get the full axis to show. Can I set the original zoom so that it shows the entire plot?
> dput(analysis[,c(1:3)])
structure(list(L = c(60, 70, 80, 90, 100, 110, 120, 130, 140,
60, 70, 80, 90, 100, 110, 120, 130, 140, 60, 70, 80, 90, 100,
110, 120, 130, 140, 60, 70, 80, 90, 100, 110, 120, 130, 140),
S = c(6, 6, 6, 6, 6, 6, 6, 6, 6, 7.5, 7.5, 7.5, 7.5, 7.5,
7.5, 7.5, 7.5, 7.5, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10.5, 10.5,
10.5, 10.5, 10.5, 10.5, 10.5, 10.5, 10.5), theta = c(0.387648377238727,
0.365065109815399, 0.361945691353903, 0.308994736435413,
0.31312106684787, 0.347902392899031, 0.322177548286843, 0.313365432864246,
0.318566760330453, 0.329343960085812, 0.4305266050694, 0.412161930763136,
0.405615100181224, 0.342671510183088, 0.379821799998522,
0.351607159033827, 0.338622255013142, 0.330437773555393,
0.359828622589832, 0.43564477128519, 0.446968516154636, 0.364471191945187,
0.311372659889749, 0.343410820556976, 0.319743944825857,
0.367342095248675, 0.303374120182854, 0.402025212310935,
0.486427167733943, 0.402463557214462, 0.380560495098558,
0.32606222794188, 0.383477501221339, 0.315207079133179, 0.359243336292084,
0.338734658604223)), class = "data.frame", row.names = c(NA, -36L))
fig <- plot_ly(analysis, x = ~L, y = ~S, z = ~theta) %>%
add_markers(opacity = 0.6) %>%
layout(scene = list(xaxis = list(title = 'Span Length (ft)'),
yaxis = list(title = 'Girder Spacing (ft)'),
zaxis = list(title = 'End Rotation (deg)')),
margin = list(b=130), annotations =
list(x = 0.9, y = -0.2, text = "<i>Figure 4. Relationship between the input variables used in the parametric study.</i>",
showarrow = F, xref='paper', yref='paper',
xanchor='right', yanchor='auto', xshift=0, yshift=0,
font=list(size=15)))
Below is a screenshot of the HTML output:

You'll have to find a combination of x, y, and z in scene = list(camera = list(eye = list(x=1.5, y=3, z = 0.1))) that suits your needs.
Your code snippet is not reproducible, but we can recreate the problem using:
fig <- plot_ly(z = ~volcano)
fig <- fig %>% add_surface()
fig
Now, just include:
scene = list(camera = list(eye = list(x=1.5, y=3, z = 0.1)))
fig <- fig %>% layout(title = "changed zoom", scene = scene)
And you'll get:

Related

How can I change the trace order in plotly polarchart in R?

I need to display the differences in area using polarchart in R plotply. It seems that my code works fine, However I need to switch the traces, so that the "M0" layer (trace) will be the one on top and "M2" trace on the bottom. Could anyone help me with this, considering that I have tried multiple options and none have worked so far.
My R code:
x1 <- c(
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36,
36, 34, 32, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0
)
y1 <- c(
126.1413, 122.5064, 120.5929, 119.5620, 116.2632, 113.2340, 111.8527,
112.5675, 116.6128, 112.6579, 104.5264, 103.5137, 101.0783, 104.8868,
107.8864, 109.0920, 95.3229, 101.3696, 112.2920, 114.7041, 107.6714,
107.5115, 100.6170, 107.9576, 108.9578, 113.2368, 114.9524, 119.4507,
122.6751, 123.1861, 124.9997, 125.9652, 124.7454, 123.8936, 128.1220,
129.7844, 129.7762, 117.2343
)
x2 <- c(
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36,
36, 34, 32, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0
)
y2 <- c(
125.52385, 119.07241, 116.24269, 116.22503, 113.72144, 113.23399,
108.94401, 108.83963, 109.37008, 107.46098, 104.52637, 102.99718,
96.47646, 93.31721, 92.08402, 96.04877, 95.32290, 101.36958, 112.29199,
114.70411, 107.67138, 107.51151, 108.39729, 107.95755, 108.95785,
113.23678, 117.89176, 124.14630, 126.53308, 132.59236, 131.69146,
132.94295, 131.67062, 128.36539, 129.79911, 130.99317, 131.97529, 125.52385
)
x3 <- c(
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 30, 28, 26,
24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0
)
y3 <- c(
126.14132, 122.50643, 120.59295, 119.56199, 116.26324, 112.29014,
111.85268, 112.56755, 116.61283, 112.65789, 104.34224, 96.50043,
101.07827, 104.88684, 103.69290, 109.09203, 111.50719, 116.95312,
115.86528, 119.68691, 114.95241, 119.45073, 124.83299, 131.63141,
130.78950, 125.96519, 124.74543, 123.89356, 128.12202, 129.78436,
129.77622, 126.14132
)
p <- plot_ly(
type = "scatterpolar",
mode = "lines"
) %>%
add_trace(
name = "M0",
r = as.numeric(y1),
theta = as.numeric(x1),
thetaunit = "degrees",
fill = "toself",
line = list(
color = "#1B98E0FF"
),
fillcolor = "#1B98E0FF"
) %>%
add_trace(
name = "M1",
r = as.numeric(y2),
theta = as.numeric(x2),
thetaunit = "degrees",
fill = "toself",
line = list(
color = "#1B98E0BF"
),
fillcolor = "#1B98E0BF"
) %>%
add_trace(
name = "M2",
r = as.numeric(y3),
theta = as.numeric(x3),
thetaunit = "degrees",
fill = "toself",
line = list(
color = "#1B98E08C"
),
fillcolor = "1B98E08C"
) %>%
layout(polar = list(
domain = list(
x = c(1, 1),
y = c(1, 1)
),
sector = c(0, 100),
angularaxis = list(
direction = "clockwise",
thetaunit = "degrees",
dtick = 10,
rotation = 90
),
radialaxis = list(
range = c(0, 140), title = "µm"
)
))
I tried to change the order of the traces as well by adding the "M2" trace initially and it did not work.
I have included a reproducible example below and have edited the colors and the transparency so it's easier to see each layer. The first plot is a copy of OP's original plot and the second plot has M1 as the top most layer. In order to make M1 the top most layer, I had to move it to the very bottom. It also looks like the legend follows this pattern; so even though the legend shows M1 on bottom in the second plot, you can tell that M1 (in red) is on top because the M1 label appears whenever you hover over a section that contains M1 (red) and M2 (blue) traces.
library(plotly)
x1 <- c(0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 36, 34, 32, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 6, 4, 2, 0)
y1 <- c(126.1413,122.5064,120.5929,119.5620,116.2632,113.2340,111.8527,112.5675,116.6128,112.6579,104.5264,103.5137,101.0783,104.8868,107.8864,109.0920,95.3229,101.3696,112.2920,114.7041,107.6714,107.5115,100.6170,107.9576,108.9578,113.2368,114.9524,119.4507,122.6751,123.1861,124.9997,125.9652,124.7454,123.8936,128.1220,129.7844,129.7762,117.2343)
x2 <- c(0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,36,34,32,30,28,26,24,22,20,18,16,14,12,10,8,6,4,2,0)
x3 <- c(0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,30,28,26,24,22,20,18,16,14,12,10,8,6,4,2,0)
y2 <- c(125.52385,119.07241,116.24269,116.22503,113.72144,113.23399,108.94401,108.83963,109.37008,107.46098,104.52637,102.99718,96.47646,93.31721,92.08402,96.04877,95.32290,101.36958,112.29199,114.70411,107.67138,107.51151,108.39729,107.95755,108.95785,113.23678,117.89176,124.14630,126.53308,132.59236,131.69146,132.94295,131.67062,128.36539,129.79911,130.99317,131.97529,125.52385)
y3 <- c(126.14132,122.50643,120.59295,119.56199,116.26324,112.29014,111.85268,112.56755,116.61283,112.65789,104.34224,96.50043,101.07827,104.88684,103.69290,109.09203,111.50719,116.95312,115.86528,119.68691,114.95241,119.45073,124.83299,131.63141,130.78950,125.96519,124.74543,123.89356,128.12202,129.78436,129.77622,126.14132)
# original plot
plot_ly(type = 'scatterpolar', mode = 'lines') %>%
add_trace(name = "M0", r = as.numeric(y1), theta = as.numeric(x1),
thetaunit = "degrees", fill = 'toself',
line = list(color = 'rgba(255,255,0,0.25)'),
fillcolor = 'rgba(255,255,0,0.25)') %>%
add_trace(name = "M1", r = as.numeric(y2), theta = as.numeric(x2),
thetaunit = "degrees", fill = 'toself',
line = list(color = 'rgba(255,87,55,0.75)'),
fillcolor = 'rgba(255,87,55,0.25)') %>%
add_trace(name = "M2", r = as.numeric(y3), theta = as.numeric(x3),
thetaunit = "degrees", fill = 'toself',
line = list(color = 'rgba(0,0,255,0.25)'),
fillcolor = 'rgba(0,0,255,0.25)') %>%
layout(polar = list(domain = list(x = c(1,1), y = c(1,1)), sector = c(0,100),
angularaxis = list(direction = 'clockwise', thetaunit = 'degrees', dtick = 10, rotation = 90),
radialaxis = list( range = c(0,140), title = "µm")))
# where m1 is on top
plot_ly(type = 'scatterpolar', mode = 'lines') %>%
add_trace(name = "M0", r = as.numeric(y1), theta = as.numeric(x1),
thetaunit = "degrees", fill = 'toself',
line = list(color = 'rgba(255,255,0,0.25)'),
fillcolor = 'rgba(255,255,0,0.25)') %>%
add_trace(name = "M2", r = as.numeric(y3), theta = as.numeric(x3),
thetaunit = "degrees", fill = 'toself',
line = list(color = 'rgba(0,0,255,0.25)'),
fillcolor = 'rgba(0,0,255,0.25)') %>%
add_trace(name = "M1", r = as.numeric(y2), theta = as.numeric(x2),
thetaunit = "degrees", fill = 'toself',
line = list(color = 'rgba(255,87,55,0.75)'),
fillcolor = 'rgba(255,87,55,0.25)') %>%
layout(polar = list(domain = list(x = c(1,1), y = c(1,1)), sector = c(0,100),
angularaxis = list(direction = 'clockwise', thetaunit = 'degrees', dtick = 10, rotation = 90),
radialaxis = list( range = c(0,140), title = "µm")))

plotting a graph with multiple bars in R

I am struggling to plot the following data and think it is because of the format of the data.
structure(list(HE_Provider = c("Coventry University", "The University of Leicester",
"Total"), Bath_and_North_East_Somerset = c(15, 20, 205), Bedford = c(85,
90, 1040), Blackburn_with_Darwen = c(10, 20, 95), Blackpool = c(10,
5, 60), `Bournemouth,_Poole_and_Christchurch` = c(35, 15, 285
), Bracknell_Forest = c(15, 10, 210), Buckinghamshire = c(195,
145, 1835), Cambridgeshire = c(130, 160, 2500), Central_Bedfordshire = c(115,
70, 1120), Cheshire_East = c(45, 55, 935), Cheshire_West_and_Chester = c(25,
40, 535), City_of_Bristol = c(40, 35, 390), City_of_Derby = c(65,
135, 4115), City_of_Kingston_upon_Hull = c(25, 20, 265), City_of_Leicester = c(315,
1275, 6860), City_of_Nottingham = c(65, 145, 5405), City_of_Plymouth = c(15,
10, 135), City_of_Portsmouth = c(15, 15, 130), City_of_Southampton = c(15,
20, 140), `City_of_Stoke-on-Trent` = c(50, 15, 475), City_of_York = c(35,
20, 350), Cornwall = c(25, 25, 300), County_Durham = c(20, 40,
330), Cumbria = c(30, 20, 305), Darlington = c(0, 15, 110), Derbyshire = c(100,
145, 6925), Devon = c(50, 50, 630), Dorset = c(30, 20, 285),
East_Riding_of_Yorkshire = c(75, 45, 760), East_Sussex = c(55,
50, 650), Essex = c(365, 180, 3320), Gloucestershire = c(150,
85, 905), Greater_London = c(5550, 1930, 18285), Greater_Manchester = c(245,
280, 2820), Halton = c(5, 10, 80), Hampshire = c(180, 120,
1485), Hartlepool = c(5, 10, 55), Herefordshire = c(50, 15,
235), Hertfordshire = c(385, 270, 4815), Isle_of_Wight = c(10,
5, 90), Isles_of_Scilly = c(0, 0, 0), Kent = c(365, 195,
2590), Lancashire = c(75, 125, 985), Leicestershire = c(540,
980, 8010), Lincolnshire = c(145, 190, 7710), Luton = c(105,
75, 685), Medway = c(95, 35, 425), Merseyside = c(75, 120,
975), Middlesbrough = c(10, 5, 65), Milton_Keynes = c(265,
170, 2205), Norfolk = c(120, 115, 2410), North_East_Lincolnshire = c(20,
10, 810), North_Lincolnshire = c(20, 20, 810), North_Somerset = c(25,
15, 205), North_Yorkshire = c(500, 80, 1160), Northamptonshire = c(680,
510, 7505), Northumberland = c(10, 25, 235), Nottinghamshire = c(140,
185, 9410), Oxfordshire = c(280, 135, 1785), Peterborough = c(85,
135, 1560), Reading = c(75, 25, 260), Redcar_and_Cleveland = c(5,
5, 90), Rutland = c(5, 35, 345), Shropshire = c(60, 30, 500
), Slough = c(95, 40, 270), Somerset = c(40, 40, 490), South_Gloucestershire = c(40,
25, 310), South_Yorkshire = c(105, 180, 3220), `Southend-on-Sea` = c(35,
25, 345), Staffordshire = c(370, 150, 3825), `Stockton-on-Tees` = c(20,
15, 145), Suffolk = c(115, 115, 1935), Surrey = c(195, 155,
2900), Swindon = c(50, 25, 225), Telford_and_Wrekin = c(60,
20, 360), Thurrock = c(140, 40, 370), Torbay = c(5, 5, 65
), Tyne_and_Wear = c(45, 60, 680), Warrington = c(20, 20,
290), Warwickshire = c(2080, 210, 2825), West_Berkshire = c(35,
25, 300), West_Midlands = c(8315, 915, 8220), West_Sussex = c(105,
95, 1115), West_Yorkshire = c(200, 245, 3005), Wiltshire = c(90,
55, 630), Windsor_and_Maidenhead = c(40, 25, 405), Wokingham = c(70,
35, 395), Worcestershire = c(350, 110, 1350), `England_(county_unitary_authority_unknown)` = c(0,
10, 770), Total_England = c(24990, 11530, 154930), Total = c(25380,
11845, 158480)), row.names = c(NA, -3L), class = "data.frame")
I would like to plot the Region on the bottom but don't have a title for these regions, with the numbers up the y axis and the fill being the university.
This type of problems generally has to do with reshaping the data. The format should be the long format and the data is in wide format. See this post on how to reshape the data from wide to long format.
Reshape the data and plot with geom_col.
suppressPackageStartupMessages({
library(dplyr)
library(tidyr)
library(ggplot2)
})
df1 %>%
select(-matches("England"), -matches("Total")) %>%
pivot_longer(-HE_Provider, names_to = "Region") %>%
ggplot(aes(Region, value, fill = HE_Provider)) +
geom_col() +
theme_bw(base_size = 10) +
theme(axis.text.x = element_text(size = 7, angle = 75, vjust = 1, hjust = 1),
legend.position = "bottom")
Created on 2022-12-06 with reprex v2.0.2
We could bring the data in long format. For y we used log scale:
library(tidyverse)
df %>%
pivot_longer(-HE_Provider) %>%
group_by(HE_Provider, name) %>%
summarise(sum_value = sum(value)) %>%
ggplot(aes(x=name, y=log(sum_value), fill=HE_Provider))+
geom_col(position=position_dodge())+
theme(axis.text.x = element_text(angle = 45, vjust = 0.5, hjust=1))

How to add or annotate Latex formula as annotation in boxplot() in R?

I want to annotate my boxplot (create in Base R) with some text and latex formula's, I tried with $..formula..$, but didn't work. Does anyone know a solution?
i = c(1:20)
X = c(13, 18, 25, 58, 25, 31, 39, 42, 17, 35, 46, 22, 18, 20, 26, 14, 33, 19, 20, 21)
df = data.frame(i, X)
boxplot(df$X, data=df, main="Belminuten Data",
xlab=" ", ylab="Aantal Belminuten",
frame = FALSE,
ylimit = c(10, 60),
range=3)
text(x = c(1.3), y = 60, "n = 20") # n should be in italic or in formula style
text(x = c(.7), y = 23.5, "Med = 23.5")
text(x = c(.7), y = 18.5, "Q_1 = 18.5")
library(latex2exp)
i = c(1:20)
X = c(13, 18, 25, 58, 25, 31, 39, 42, 17, 35, 46, 22, 18, 20, 26, 14,
33, 19, 20, 21)
df = data.frame(i, X)
boxplot(df$X, data=df, main="Belminuten Data",
xlab=" ", ylab="Aantal Belminuten",
frame = FALSE,
ylimit = c(10, 60),
range=3)
text(x = c(1.3), y = 60, TeX('$n = 20$'))
text(x = c(.7), y = 13.0, TeX('$Min = 13$'))
text(x = c(.7), y = 18.5, TeX('$Q_1 = 18.5$'))
text(x = c(.7), y = 23.5, TeX('$Med = 23.5$'))
text(x = c(.7), y = 34.0, TeX('$Q_3 = 34$'))
text(x = c(.7), y = 58.0, TeX('$Max = 58$'))

ggplot visualization questions

for visualized my data, I used gplot.
Question: Why "colour" doesn't change, and is it possible to do type = "h" like in basic plot?
print(qplot(roundpop, Observation, data=roundpopus), shape = 5, colour = "blue") # i tryed with "" and without.
And if it's possible to change type to histogram, like on second picture, can I draw a line by the top of lines?
Like that:
and maybe to write labels (states) on the top of the lines. Because I know how to give a name only for dots on basic plot.
Thank you!
Here are some options, which you may want to tweak according to your needs:
library(ggplot2)
df <- structure(list(x = c(1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6,
6, 6, 7, 7, 7, 7, 8, 9, 10, 10, 10, 12, 13, 13, 20, 20, 27, 39
), y = c(33, 124, 45, 294, 160, 105, 276, 178, 377, 506, 176,
393, 247, 378, 221, 796, 503, 162, 801, 486, 268, 575, 828, 493,
252, 495, 836, 551, 413, 832, 1841, 1927), lab = c("i8g8Q", "oXlWk",
"NC2WO", "pYxBL", "Xfsy6", "FJcOl", "Ke98f", "K2mCW", "g4XYi",
"ICzWp", "7nqrK", "dzhlC", "JagAW", "0bObp", "8ljIW", "E8OZR",
"6Tuxz", "3Grbq", "xqsld", "BvuJT", "JXi2N", "eSDYS", "OYVWN",
"vyWzK", "6AKxk", "nCgPx", "8lHrq", "kWAGm", "E08Rd", "cmIYY",
"btoUm", "k6Iek")), .Names = c("x", "y", "lab"), row.names = c(NA,
-32L), class = "data.frame")
p <- ggplot(df, aes(x, y))
gridExtra::grid.arrange(
p + geom_point(),
p + geom_point() + geom_text(aes(label = lab), angle = 60, hjust = 0, size = 2),
p + geom_segment(aes(xend=x, yend=0)),
p + geom_segment(aes(xend=x, yend=0)) + geom_line(color = "red", size = 2) ,
p + geom_segment(aes(xend=x, yend=0)) + geom_smooth(span = .4, se = FALSE, color = "red", size = 2)
)

Area plot with missing values in base R

I want to draw an area plot for which the base of the polygon is zero and the data lines are connected to the base by vertical segments at every data break (that is the beginning, the end and possible NAs/NaN).
I drew this:
I had to force vertical down ward segments where the serie is interrupted with NAs, and I did this transforming NAs in 0s. But that doesn't produce vertical segments but polygon lines that reach the following 0s. I solved the problem for the beginning and the end of the series, adding a (y = 0, x = 0) point on both sides on the serie.
But this doesn't fix the problem if the NAs are inside the serie.
Any idea?
here's an example code (different image):
pollen <- c(45, 257.4, 24.67, 54.6, 89.4, 297, 471.25, 1256.5, 312.25, 969.2, 787.5, 425, NaN, 76.6, 42.67, 38.5, 20.2, 5.67, 15.8, 13.2, 11, 6.25, 6.67, 2.3, 0.5, 30.8, 3.75, 3, 2, 2.2, 3.25, 4.5, 9.6, 15.8, 200.2, NaN)
weeks.vec <- c(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40)
plot.ts(y = pollen, x = weeks.vec, col = 'red', ylab = 'Pollen', xlab = 'Weeks', lwd = 3, xy.labels = F, xy.lines = T)
pollen[is.na(pollen)] <- 0
poly.y <- c(0,pollen,0)
poly.x <- c(weeks.vec[1], weeks.vec, weeks.vec[length(weeks.vec)])
polygon(y = poly.y, x = poly.x, density = NA,border = NA, col = rgb(1,0,0, .3))
I'd use ggplot2:
pollen <- c(45, 257.4, 24.67, 54.6, 89.4, 297, 471.25, 1256.5, 312.25, 969.2, 787.5, 425, NaN, 76.6, 42.67, 38.5, 20.2, 5.67, 15.8, 13.2, 11, 6.25, 6.67, 2.3, 0.5, 30.8, 3.75, 3, 2, 2.2, 3.25, 4.5, 9.6, 15.8, 200.2, NaN)
weeks.vec <- c(5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40)
DF <- data.frame(pollen, weeks.vec)
library(ggplot2)
ggplot(DF, aes(x = weeks.vec, y = pollen)) +
geom_ribbon(aes(ymin = 0, ymax = pollen),
colour = NA, fill = "red", alpha = 0.3) +
geom_line(colour = "red") +
geom_point(colour = "red", size = 3) +
xlab("Week") + ylab("Pollen") +
theme_bw()
But if you must use base plots:
plot.ts(y = pollen, x = weeks.vec, col = 'red',
ylab = 'Pollen', xlab = 'Weeks', lwd = 3,
xy.labels = F, xy.lines = T)
g <- cumsum(!is.finite(pollen))
for (i in unique(g)) {
y <- pollen[g == i]
x <- weeks.vec[g == i]
x <- x[is.finite(y)]
y <- y[is.finite(y)]
x <- c(x, rev(x))
y <- c(y, y * 0)
polygon(y = y, x = x, density = NA,border = NA, col = rgb(1,0,0, .3))
}

Resources