Alberto De Benedittis
Alberto De Benedittis

Reputation: 91

Align double axis in R plotly

I would like to create a plot with a double axis. The data can be found here below :

dput(df)
structure(list(OBS_DATE = structure(c(10957, 11048, 11139, 11231, 
11323, 11413, 11504, 11596, 11688, 11778, 11869, 11961, 12053, 
12143, 12234, 12326, 12418, 12509, 12600, 12692, 12784, 12874, 
12965, 13057, 13149, 13239, 13330, 13422, 13514, 13604, 13695, 
13787, 13879, 13970, 14061, 14153, 14245, 14335, 14426, 14518, 
14610, 14700, 14791, 14883, 14975, 15065, 15156, 15248, 15340, 
15431, 15522, 15614, 15706, 15796, 15887, 15979, 16071, 16161, 
16252, 16344, 16436, 16526, 16617, 16709, 16801, 16892, 16983, 
17075, 17167, 17257, 17348, 17440, 17532, 17622, 17713, 17805, 
17897, 17987, 18078, 18170, 18262, 18353, 18444, 18536, 18628, 
18718, 18809, 18901, 18993, 19083), class = "Date"), Net_operating_surplus_to_value_added = c(36.9656739231445, 
36.8689864882343, 36.6317520083419, 36.8317643474959, 37.6935121500197, 
38.5018034788891, 38.9957638139427, 39.1885608912447, 38.6092136149497, 
38.2770183401821, 38.4489120097893, 38.3537299053262, 38.4156940299523, 
38.137139643167, 37.8894433308562, 37.7064555602493, 37.9839392196746, 
38.3746788684954, 38.6020160570843, 38.8268119307867, 38.5613405710757, 
38.7101242715524, 38.8273476727589, 38.8869873772993, 39.720479442795, 
39.6658712861905, 39.8767955423033, 40.3180414586718, 40.9445739166353, 
41.4504448781142, 42.1689391948721, 42.5475515086736, 42.0065894935759, 
41.8235800428308, 41.0535110327202, 39.3776111728045, 37.2918935656955, 
34.7987917589771, 33.6060430866382, 33.2333240074088, 33.5352650692288, 
34.0870394255266, 34.4296192872216, 34.9379435365405, 35.4951911949687, 
35.5398028603395, 35.5785861381144, 35.0406777120541, 34.4467029671623, 
33.4624900670117, 32.6226354628198, 31.8258664477327, 31.2901452931081, 
31.3585743099158, 31.6843235126606, 32.0760017276417, 32.5304675296323, 
32.5073363450562, 32.6352221514581, 32.7957586698719, 33.3467283704801, 
33.9694837972178, 34.5433408050505, 35.1956294062996, 35.0685963830019, 
35.607294642208, 35.581902998671, 35.7209284106957, 35.9308759449264, 
35.6894948426784, 36.2947609108182, 36.2938680510367, 36.2653856458804, 
36.08587682079, 35.182630097821, 34.6910386509771, 34.5456518897842, 
34.046625027426, 34.2605143927775, 34.2141127409063, 33.1221766349027, 
31.0095937520034, 30.2453076663821, 30.2414563984248, 31.704392011148, 
34.5010174977904, 34.8147384445836, 34.7697905115992, 34.43625109411, 
33.8841955271951), Met_retained_earnings_to_value_added = c(3.65946513678856, 
2.99463238024132, 2.49514650123736, 3.02457398855396, 3.52170627766491, 
3.65874887644949, 3.75035993710115, 4.19023687395792, 5.03705154102929, 
5.57632125508043, 8.2495415198731, 9.1177952075909, 8.39854897090696, 
7.90761699297047, 6.61882380938546, 5.82196030311438, 6.14631242125481, 
6.17680298128492, 6.07542512868537, 6.01032154224047, 5.66854842968337, 
5.47974183094731, 5.26498409983987, 5.0098922839463, 5.5332050888931, 
4.46960255520707, 4.37466881326977, 4.15148205815225, 4.52903352953872, 
4.45114690933355, 5.03266104719299, 4.95052573926497, 3.97052831893563, 
3.50569271340267, 2.44196835732784, 1.5954474561901, 0.389019198525782, 
0.491438385056609, 1.53710358969239, 3.326229908946, 5.04170916975847, 
5.60436479062756, 6.57740686481843, 6.02041199986632, 5.60803794337375, 
5.78906824166877, 4.75880249860857, 5.05756309766792, 4.51410756786046, 
4.34574033479928, 3.45056503904027, 2.77862946386903, 3.39068127274666, 
3.87423424368168, 5.060146724212, 5.59504392224852, 5.94120589707917, 
5.38305476870492, 5.44128431403496, 5.9577367772693, 6.5888030147431, 
7.1133680406906, 7.53087422774044, 8.18386901533204, 8.2264735443145, 
8.95382429921373, 9.51201069521699, 9.5114820156883, 9.64064423866319, 
9.05512739701095, 9.40881852811793, 10.0114821239402, 9.5692691653021, 
9.0906823904455, 8.47113772060278, 7.64711815518838, 8.0943097283881, 
7.77194975031624, 8.04157404171203, 8.3642302611957, 7.11751092092824, 
6.1040017121415, 5.52587902763856, 5.87309706295293, 7.38715617317306, 
10.082162546155, 10.5674522055678, 9.83495111956979, 9.30377793666422, 
6.87773746393322)), class = "data.frame", row.names = c(NA, -90L
))

The following is the code that I am using

min_Date <-  as.Date("2021-01-01")  
max_Date <- df$OBS_DATE[length(df$OBS_DATE)]
start_point <-  c(min_Date, max_Date)

chart2 <- plot_ly(x = df$OBS_DATE, y = df$Net_operating_surplus_to_value_added, type = 'scatter',  mode = 'lines', name = "Net operating surplus to value added (LHS)", line = list(color = "#003299") ) %>% 
            
add_trace(y = df$Met_retained_earnings_to_value_added,  name = "Met retained earnings to value added (RHS)", line = list(color = "#FFB400" ), yaxis = "y2") %>% 

layout(barmode = 'relative', barbase = 0, xaxis = list(range = start_point), yaxis = list(range = c(30,44)),  yaxis2 = list(overlaying = "y", side = "right",range = c(0, 14)))

In this way I am able to align the axis in the zoomed version of the chart enter image description here]

However, when I look at the whole series the grid lines become misaligned.

enter image description here

> min(df$Net_operating_surplus_to_value_added)
[1] 30.24146
> max(df$Net_operating_surplus_to_value_added)
[1] 42.54755

> max(df$Met_retained_earnings_to_value_added)
[1] 10.56745
> min(df$Met_retained_earnings_to_value_added)
[1] 0.3890192

What I can do to solve this problem ?

Upvotes: 1

Views: 311

Answers (1)

Kat
Kat

Reputation: 18714

I'm not able to double-click on the plot to get the entire dataset. However, if I click on 'autoscale', I can get all of the data. When you define a range, it sets the scale to manual. By selecting 'autoscale', you're erasing those settings.

However, if you want to start as you have, and maintain the scale ratio, then use scaleratio, constraintowards, and add two invisible traces to account for the disparity in ranges (if we set ratio = 1, it's literal).

Add a line that has a y value that ranges between 30 and 44, aligned to y. Add another line that has a y value that ranges between 0 and 14, aligned to y2.

Check it out.

(chart2 <- plot_ly(x = df$OBS_DATE, 
                  y = df$Net_operating_surplus_to_value_added, 
                  type = 'scatter',  mode = 'lines', 
                  name = "Net operating surplus to value added (LHS)",
                  line = list(color = "#003299") ) %>% 
  add_trace(y = c(30, rep(44, nrow(df) - 1)), line = list(width = .0001),
            showlegend = F) %>%                      # <----- hidden trace
  add_trace(y = df$Met_retained_earnings_to_value_added, 
            name = "Met retained earnings to value added (RHS)", 
            line = list(color = "#FFB400" ), yaxis = "y2") %>% 
  add_trace(y = c(0, rep(14, nrow(df) - 1)), line = list(width = .0001),
            yaxis = "y2", showlegend = F) %>%        # <----- hidden trace
  layout(barmode = 'relative', barbase = 0, 
         xaxis = list(range = start_point), 
         yaxis = list(range = c(30, 44)),  
         yaxis2 = list(overlaying = "y", 
                       scaleratio = 1, scaleanchor = "y",
                       constraintoward = "bottom",
                       side = "right", range = c(0, 14))))

Now when you autoscale, you're going to maintain that same ratio you wanted to maintain.

Additionally, depending on what you're doing with this graph, you may want to have the two invisible traces called first, so they're on the bottom.

enter image description here

Upvotes: 1

Related Questions