Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Image truncated and white borders using gtsave() function #66

Open
Fedess1986 opened this issue Jan 29, 2024 · 9 comments
Open

Image truncated and white borders using gtsave() function #66

Fedess1986 opened this issue Jan 29, 2024 · 9 comments

Comments

@Fedess1986
Copy link

I'm trying to export a gt table created using the gtsave() function, as PNG file.

The generated PNG has some white border at the left, and sometime at botton and top too. Also, the right side of the image is cropped/truncated.
The gtsave() generates a html temp file to get the shot, which I can locate and check the table looks correct (I open that html file with chrome).

I tryed changing and playing vwidth, vheight, zoom, expand, and selector arguments, with no luck.

I can upload some screenshots for references, if needed

@Fedess1986 Fedess1986 changed the title Image truncated and white borders using gtsave() funcition Image truncated and white borders using gtsave() function Jan 29, 2024
@gadenbuie
Copy link
Member

Hi @Fedess1986 and thanks for the report. Screenshots might be helpful, but it'd be even more helpful to include a reproducible example (or reprex).

@Fedess1986
Copy link
Author

For some reason I cannot make reprex() work, anyway I did my best.


library(dplyr)
library(gt)
library(gtExtras)


# I just create a table with similar data I work with

table <- data.frame(
           Provider = c("provider1_a_long_name_for_testing", "provider2", "provider3", "provider4", "provider5", "provider6", "provider7", "provider8", "provider9", "provider10"),
           Expenses = c(10000000, 8000000, 7000000, 4000000, 3500000, 3000000, 2000000, 500000,450000,200000),
           Value1 = c(100,105,110,120,130,150,160,170,180,190)*1001,
           Value2 = c(200,205,209,220,230,250,260,270,280,290)*1002,
           Value3_longer = c(300,305,309,320,330,350,360,370,380,390)*1003
           )

Qty_evolution  <-  list(
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5))
           )

table$Qty_evolution <- Qty_evolution



# Here I create the gttable I would like to export as PNG image

gt_table <-  table %>% select(Provider, Expenses, Qty_evolution, Value1, Value2, Value3_longer) %>%   gt() %>% 
  tab_header(
    title = "The title of this table",
    subtitle = "Then, the subtitle")   %>% 
  tab_source_note(source_note = "ALso I'm using a source note."  ) %>% 
  tab_style(style = cell_text(align = "center"),locations = cells_source_notes()) %>%  
   tab_spanner(
    label = "Actual value - and giving this a long name too",
    columns = c(Value1, Value2, Value3_longer)
  ) %>% 
  fmt_currency(columns = Value1:Value3_longer, decimals = 0, sep_mark = ".",
  dec_mark = ",") %>% 
  gt_plt_bar(column = Expenses, keep_column = FALSE, color = "#5064FF",width = 50) %>% gt_plt_sparkline(column = Qty_evolution, fig_dim = c(14, 60), palette = c("#7EC9FF", "gray96", "green", "red", "lightgrey"),) %>% 
  tab_options(table.background.color = ("gray19"), table.font.color = "gray90", heading.title.font.size = 24,  heading.title.font.weight = "bold" ,heading.subtitle.font.size = 20,
table.font.size = 14,
column_labels.font.size = 16,
  row_group.border.top.color = "gray35",
  table.border.top.color = "gray35",
  heading.border.bottom.color = "gray35",
table_body.hlines.color = "gray35",
table_body.vlines.color = "gray35", 
table_body.border.top.color = "gray35",
table_body.border.bottom.color = "gray35",
heading.border.lr.color = "gray35",
 column_labels.border.bottom.color = "gray35",
column_labels.vlines.color = "gray35", 
column_labels.border.lr.color = "gray35"
  )
 

# This is the functions that internally uses webshot
gtsave(gt_table, filename = "test.PNG", zoom = 1)

 

@Fedess1986
Copy link
Author

Fedess1986 commented Jan 29, 2024

Also, locating the html file, what I do is:
Edit: I share this part because I believe it helps finding out where the problem is or is not, I think it is not related with th gt package, as the result using directly webshot and coming from a html file is the same.



webshot2::webshot(url = "reproducible.html", file = "test2.png",
                  zoom = 1)

And result is exactly the same

@gadenbuie
Copy link
Member

Thanks for the example code @Fedess1986. I'm not surprised that reprex() gave you some trouble, this kind of issue tends to be tricky for reprex().

I linked to the package for its helpful advice about creating a reproducible, minimal example. Are all of the packages and code in your example required to reproduce the problem? If not, it would also be helpful if you could reduce the example code to the smallest subset of packages and lines and are needed to reproduce the issue. (Often you'll find important clues in this process.)

@Fedess1986
Copy link
Author

Thanks for the advice. I managed to rewrite the code without the "dplyr" package. Also I reduced the code by quitting many visual options that are not needed, and the issue still happens.
The "gt" package is required to create the table which contains graphics inside it, those graphics (like the sparkline) created with "gtExtras" package. The result is what I'm trying to render/get the screenshot, so both packages are needed, as I understand.

Here is the new code. I hope this helps 😀


library(gt)
library(gtExtras)


# I just create a table with similar data I work with

table <- data.frame(
           Provider = c("provider1_a_long_name_for_testing", "provider2", "provider3", "provider4", "provider5", "provider6", "provider7", "provider8", "provider9", "provider10"),
           Expenses = c(10000000, 8000000, 7000000, 4000000, 3500000, 3000000, 2000000, 500000,450000,200000))

Qty_evolution  <-   list(
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5)),
           c(rep(c(5,8,10,15,25,20,17,18,22,16), 5))
           )

table$Qty_evolution <- Qty_evolution

table <-  cbind(table,data.frame(
           Value1 = c(100,105,110,120,130,150,160,170,180,190)*1001,
           Value2 = c(200,205,209,220,230,250,260,270,280,290)*1002,
           Value3_longer = c(300,305,309,320,330,350,360,370,380,390)*1003
           ))




# Here I create the gttable I would like to export as PNG image

gt_table <- gt(table) 
gt_table <- tab_header(gt_table, title = "The title of this table")
gt_table <- tab_source_note(gt_table, source_note = "Also I'm using a source note.")
gt_table <- tab_style(gt_table, style = cell_text(align = "center"),locations = cells_source_notes())
gt_table <- tab_spanner(gt_table,  label = "Actual value - and giving this a long name too", columns = c(Value1, Value2, Value3_longer)) 
gt_table <- fmt_currency(gt_table, columns = Value1:Value3_longer, decimals = 0, sep_mark = ".", dec_mark = ",")
gt_table <- gt_plt_bar(gt_table, column = Expenses, keep_column = FALSE, color = "#5064FF",width = 50)
gt_table <- gt_plt_sparkline(gt_table,column = Qty_evolution, fig_dim = c(14, 60), palette = c("#7EC9FF", "gray96", "green", "red", "lightgrey"))
  
   

# This is the functions that internally uses webshot
gtsave(gt_table, filename = "test.PNG")

@gadenbuie
Copy link
Member

gadenbuie commented Jan 30, 2024

Thanks @Fedess1986, I can reproduce your issue and I have a quick solution for you.

webshot2::webshot() has two argument to control the width and height of the virtual browser screen: vwidth and vheight. These are set to 992x774 by default, but your table is wider than 992 pixels. If you set vwidth wider, gtsave() will pass that value to webshot() and you'll get the uncropped table image.

gtsave(gt_table, filename = "test.PNG", vwidth = 1200, vheight = 1200)

In general: it's pretty safe to set this to a larger value for saving a table.

I'm going to leave this issue open because webshot2 should probably adapt to changes I made in rstudio/chromote#129 (for my notes see rstudio/shinytest2#367 for additional context).

@Fedess1986
Copy link
Author

Thank you for the workaround and for the aditional info, I managed to make it work.

However I want to share this too:
Using the gt() library, I found I can define the pixels width of the table with tab_options( table.width = px() ) . So I set that to 900 pixels. Then, when I did gtsave(gt_table, filename = "test.PNG", vwidth = 900) and a white boder appeared at the right, again getting the table image truncated. I could fix it by increasing vwidth so I set it to 1000 pixels and then it worked fine.

FYI, the exported image has 1800 pixels width (zoom is default 2 so 900px * 2 is giving me those 1800 pixels, If I'm not wrong)

@gadenbuie
Copy link
Member

@Fedess1986 Limiting the table width is also a nice approach. Note that if the table width is less than 992px (minus some padding, so approx 980px), then you don't need to set vwidth in gtsave(). And you're right, gtsave() sets an option in webshot() to scale the images size up by a factor of 2, which is why vwdith = 900 gives an image width of 1800px. This results in better resolution in the image.

@Fedess1986
Copy link
Author

Thanks for your help and all your feedback. With your suggestions It's now working and covering my need. I'm also glad if this was helpful to you to help improving the library code.

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

No branches or pull requests

2 participants