Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Second axis with asis mode #84

Open
wants to merge 21 commits into
base: master
Choose a base branch
from

Conversation

JanMarvin
Copy link
Contributor

@JanMarvin JanMarvin commented Dec 7, 2022

Because I have a couple of cases where I need a secondary y axis. This currently only works with asis data. And I have tested only this single case down below. This fixes #9

Works quite well. I have added a secondary argument. This way it is possible to treat the secondary plot as if it is a normal plot. This code should only impact cases where a second plot is added. I'm not sure how to implement this with the basic asis = FALSE mschart output. It might need some glue code to patch everything together, but for now I do not care about this case.

Screenshot 2022-12-08 at 01 29 55

@JanMarvin JanMarvin changed the title second y axis with linechart [draft] second y axis with linechart Dec 7, 2022
@JanMarvin JanMarvin changed the title [draft] second y axis with linechart Second y axis with asis mode Dec 8, 2022
@JanMarvin

This comment was marked as outdated.

@JanMarvin

This comment was marked as outdated.

@JanMarvin JanMarvin force-pushed the sec_y_axis branch 2 times, most recently from 8f17ab5 to 59289f9 Compare April 22, 2023 14:02
@JanMarvin

This comment was marked as outdated.

Copy link
Contributor Author

@JanMarvin JanMarvin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor cleanups remain

R/ms_chart.R Outdated Show resolved Hide resolved
R/ms_chart.R Outdated Show resolved Hide resolved
R/ms_chart.R Outdated Show resolved Hide resolved
R/ms_chart.R Outdated Show resolved Hide resolved
R/ms_chart.R Show resolved Hide resolved
R/to_pml.R Outdated Show resolved Hide resolved
R/to_pml.R Outdated Show resolved Hide resolved
R/ms_chart.R Outdated Show resolved Hide resolved
@JanMarvin JanMarvin force-pushed the sec_y_axis branch 3 times, most recently from 3144692 to b87e06a Compare April 23, 2023 13:02
R/axis_codes.R Show resolved Hide resolved
R/ms_chart.R Outdated Show resolved Hide resolved
R/ms_chart.R Outdated Show resolved Hide resolved
@JanMarvin
Copy link
Contributor Author

JanMarvin commented Apr 25, 2023

Hi @davidgohel , could you review this sometime in the future, especially if you like the general idea? Unfortunately I only got it to work with asis = TRUE and have no real clue how to integrate it with the standard asis = FALSE approach. Maybe you have an idea? I have attempted to create a single data frame [edit[ and use this [/edit] via match.call() and create a single data frame from the data_series, but of course the column names do not match. Another approach would be to write every data_series to its own worksheet, but that would probably be some additional changes here and there. (And to be honest, I do not require asis = FALSE and therefore I'm a bit lazy).

My approach for this pull request was to integrate everything without touching [edit] anything but [/edit] the x$secondary objects. Therefore, the default behavior should be the same. I needed some additional arguments to identify the second y-axis, but we could wrap some of them in ... if you prefer not to announce arguments that are not usable with the default option.

Please note:

  • I hacked in a solution to disable the major and minor grids for the second y-axis because I found them visually distracting, but this should probably be handled differently.
  • In the following example, the graphs for the first and second y-axis overlap.
library(officer)
library(mschart)

t1 <- AirPassengers
t2 <- do.call(cbind, split(t1, cycle(t1)))
dimnames(t2) <- dimnames(.preformat.ts(t1))
t2 <- as.data.frame(t2)
t2$date <- as.Date(paste0(row.names(t2), "-01-01"))
nms <- c("date", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", 
         "Oct", "Nov", "Dec")
AirPass <- t2[nms]


# bar and line on first and line on second axis
bc <- AirPass |>
  ms_barchart(x = "date", y = c("Jan", "Feb"), asis = TRUE) |>
  chart_ax_x(num_fmt = "[$-fr-FR]mmm yyyy") |>
  chart_labels(title = "Title", xlab = "x axis",
               ylab = "y axis")

sec_x <- AirPass |>
  ms_linechart(x = "date", y = c("Apr", "Jul", "Oct"), asis = TRUE) |>
  chart_ax_y(second_axis = TRUE)

sec_y <- AirPass |>
  ms_linechart(x = "date", y = c("May", "Jun", "Sep"), asis = TRUE)  |>
  chart_labels(ylab = "y axis 2") |>
  chart_ax_y(second_axis = TRUE)

sec_y2 <- AirPass |>
  ms_barchart(x = "date", y = c("Mar", "Nov", "Dec"), asis = TRUE) |>
  chart_ax_y(second_axis = TRUE)

cc <- ms_combochart(bc, sec_x, sec_y, sec_y2)

### create powerpoint
doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = cc, location = ph_location_fullsize())
print(doc, target = "/tmp/example.pptx")
Screenshot 2023-05-10 at 12 45 16

[Edit] Made minor correction above and added the powerpoint example image output.
[Edit2] Updated example code

@JanMarvin

This comment was marked as outdated.

R/ms_chart.R Outdated Show resolved Hide resolved
@JanMarvin
Copy link
Contributor Author

Alright the next revision:

  • only inside ms_combochart() and without add and secondary_y
  • the user has to define second_axis if required
  • added support to disable major grids
  • Secondary x axis should be possible too

I'm waiting for a review. We could add more checks or implement combo charts for the non asis case, but the current implementation is what I need and it already works well.

t1 <- AirPassengers
t2 <- do.call(cbind, split(t1, cycle(t1)))
dimnames(t2) <- dimnames(.preformat.ts(t1))
t2 <- as.data.frame(t2)
t2$date <- as.Date(paste0(row.names(t2), "-01-01"))
nms <- c("date", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", 
         "Oct", "Nov", "Dec")
AirPass <- t2[nms]


library(openxlsx2)
library(mschart)

### barchart with line

# bar and line on first axis
wb <- wb_workbook()$add_worksheet()$add_data(x = AirPass)
dat <- wb_data(wb, dims = "A1:M13")

bc <- dat %>%
  ms_barchart(x = "date", y = c("Jan", "Feb")) %>%
  chart_ax_x(num_fmt = "[$-fr-FR]mmm yyyy") %>%
  chart_labels(title = "Title", xlab = "x axis",
               ylab = "y axis")

sec_x <- dat %>%
  ms_linechart(x = "date", y = c("Apr", "Jul", "Oct"))

cc <- ms_combochart(bc, sec_x)

wb$add_mschart(dims = "B20:L35", graph = cc)

# bar on first line on second axis
bc <- dat %>%
  ms_barchart(x = "date", y = c("Jan", "Feb")) %>%
  chart_ax_x(num_fmt = "[$-fr-FR]mmm yyyy") %>%
  chart_labels(title = "Title", xlab = "x axis",
               ylab = "y axis")

sec_y <- dat %>%
  ms_linechart(x = "date", y = c("May", "Jun", "Sep"))  %>%
  chart_ax_y(second_axis = TRUE) %>% 
  chart_labels(ylab = "y axis 2") %>% 
  chart_theme(grid_major_line_x = FALSE, grid_major_line_y = FALSE)

cc <- ms_combochart(bc, sec_y)

wb$add_mschart(dims = "B3:L18", graph = cc)


# bar and line on first and line on second axis
bc <- dat %>%
  ms_barchart(x = "date", y = c("Jan", "Feb")) %>%
  chart_ax_x(num_fmt = "[$-fr-FR]mmm yyyy") %>%
  chart_labels(title = "Title", xlab = "x axis",
               ylab = "y axis")

sec_y2 <- dat %>%
  ms_barchart(x = "date", y = c("Mar", "Nov", "Dec")) %>% 
  chart_ax_y(second_axis = TRUE)

cc <- ms_combochart(bc, sec_x, sec_y, sec_y2)

wb$add_mschart(dims = "B40:L55", graph = cc)

### linechart with bar

wb$add_worksheet()

lc <- dat %>% 
  ms_linechart(x = "date", y = c("Apr", "Jul", "Oct")) %>%
  chart_ax_x(num_fmt = "[$-fr-FR]mmm yyyy") %>% 
  chart_labels(title = "Title", xlab = "x axis",
               ylab = "y axis")
sec <- dat %>% 
  ms_barchart(x = "date", y = c("Jan", "Feb")) %>%
  chart_ax_y(second_axis = TRUE) %>% 
  chart_labels(ylab = "y axis 2")

cc <- ms_combochart(lc, sec)

wb$add_mschart(dims = "B3:L18", graph = cc)

### scatterplot

wb$add_worksheet()

sc <- dat %>% 
  ms_scatterchart(x = "Apr", y = c("Apr", "Jul", "Oct")) %>%
  chart_labels(title = "Title", xlab = "x axis",
               ylab = "y axis")
sec <- dat %>% 
  ms_barchart(x = "date", y = c("Jan", "Feb")) %>% 
  chart_ax_y(second_axis = TRUE) %>% 
  chart_labels(ylab = "y axis 2")

sec_y <- dat %>%
  ms_linechart(x = "date", y = c("May", "Jun", "Sep"))  %>%
  chart_ax_y(second_axis = TRUE) %>% 
  chart_labels(ylab = "y axis 2")

cc <- ms_combochart(sc, sec, sec_y)

wb$add_mschart(dims = "B3:L18", graph = cc)


### areachart with bar

wb$add_worksheet()

ac <- dat %>% 
  ms_areachart(x = "date", y = c("Apr", "Jul", "Oct")) %>%
  chart_ax_x(num_fmt = "[$-fr-FR]mmm yyyy") %>% 
  chart_labels(title = "Title", xlab = "x axis",
               ylab = "y axis")
sec <- dat %>% 
  ms_barchart(x = "date", y = c("Jan", "Feb"))  %>%
  chart_ax_y(second_axis = TRUE) %>% 
  chart_labels(ylab = "y axis 2")

cc <- ms_combochart(ac, sec)

wb$add_mschart(dims = "B3:L18", graph = cc)

unlink("/tmp/combo_charts.xlsx")
wb$save("/tmp/combo_charts.xlsx")

@JanMarvin
Copy link
Contributor Author

### second x axis

wb$add_worksheet()

dat1 <- wb_data(wb, sheet = 1, dims = "A1:M6")
dat2 <- wb_data(wb, sheet = 1, dims = "A1:M1;A7:M13")

ac <- dat1 %>% 
  ms_areachart(x = "date", y = c("Apr", "Jul", "Oct")) %>%
  chart_ax_x(num_fmt = "[$-fr-FR]mmm yyyy") %>% 
  chart_labels(title = "Title", xlab = "x axis",
               ylab = "y axis")

sec <- dat2 %>% 
  ms_barchart(x = "date", y = c("Jan", "Feb"))  %>%
  chart_ax_x(num_fmt = "[$-fr-FR]mmm yyyy", second_axis = TRUE) %>% 
  chart_labels(xlab = "x axis 2")

cc <- ms_combochart(ac, sec)

wb$add_mschart(dims = "B3:L18", graph = cc)

@JanMarvin
Copy link
Contributor Author

Pushed examples and documentation. There might still be some cornerstones e.g. secondary x and y axis at the same time does not work as expected, but likely nobody wants a second x axis anyways.

library(officer)
library(mschart)

t1 <- AirPassengers
t2 <- do.call(cbind, split(t1, cycle(t1)))
dimnames(t2) <- dimnames(.preformat.ts(t1))
t2 <- as.data.frame(t2)
t2$date <- as.Date(paste0(row.names(t2), "-01-01"))
nms <- c("date", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", 
         "Oct", "Nov", "Dec")
AirPass <- t2[nms]


# bar and line on first and line on second axis
fst_x <- AirPass |>
  ms_barchart(x = "date", y = c("Jan"), asis = TRUE) |>
  chart_ax_x(num_fmt = "[$-fr-FR]mmm yyyy") |>
  chart_labels(title = "Title", xlab = "x axis",
               ylab = "y axis")

fst_x2 <- AirPass |>
  ms_linechart(x = "date", y = c("Jan"), asis = TRUE)

sec_x <- AirPass |>
  ms_barchart(x = "date", y = c("Feb"), asis = TRUE) |>
  chart_ax_x(num_fmt = "[$-fr-FR]mmm yyyy", second_axis = TRUE) |>
  chart_labels(xlab = "x axis 2")

sec_x2 <- AirPass |>
  ms_linechart(x = "date", y = c("Feb"), asis = TRUE) |>
  chart_ax_x(second_axis = TRUE)

sec_y <- AirPass |>
  ms_linechart(x = "date", y = c("Mar"), asis = TRUE)  |>
  chart_labels(ylab = "y axis 2") |>
  chart_ax_y(second_axis = TRUE)

sec_y2 <- AirPass |>
  ms_barchart(x = "date", y = c("Mar"), asis = TRUE) |>
  chart_ax_y(second_axis = TRUE)

# cc <- ms_combochart(fst_x, sec_x, sec_y)
# cc <- ms_combochart(fst_x, fst_x2, sec_x, sec_x2)
cc <- ms_combochart(fst_x, fst_x2, sec_y, sec_y2)
# cc <- ms_combochart(fst_x, fst_x2, sec_x, sec_x2, sec_y, sec_y2)

### create powerpoint
doc <- read_pptx()
doc <- add_slide(doc, layout = "Title and Content", master = "Office Theme")
doc <- ph_with(doc, value = cc, location = ph_location_fullsize())
print(doc, target = "/tmp/example.pptx")

@JanMarvin JanMarvin force-pushed the sec_y_axis branch 2 times, most recently from c21ba59 to be726a1 Compare May 13, 2023 15:59
@JanMarvin JanMarvin changed the title Second y axis with asis mode Second axis with asis mode May 14, 2023
@JanMarvin
Copy link
Contributor Author

The first birthday of this PR is approaching. I'm in no rush and have been using this branch in production for quite a while, but please let me know if there is anything I can do to speed up the review process.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Is it possible to have dual y-axis plots?
1 participant