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

Unwanted cropping of ggplot2 objects #147

Open
karseneau opened this issue Aug 12, 2016 · 6 comments
Open

Unwanted cropping of ggplot2 objects #147

karseneau opened this issue Aug 12, 2016 · 6 comments

Comments

@karseneau
Copy link

There is visible cropping of .tex output from tikzDevice caused by \path[use as bounding box, ... ] and \path[clip] lines generated by the package. When these lines are removed, the tikzpicture renders correctly when compiled with knitr.

This may be an issue caused by an "artifact left from rather old PSTricks habits" according to this older answer from StackExchange.

@krlmlr
Copy link
Collaborator

krlmlr commented Aug 14, 2017

Thanks. Can you please submit a reproducible example where the cropping affects the output?

@karseneau
Copy link
Author

Thanks Kirill (@krlmlr) for getting to look at this, please see reprex below.

library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following object is masked from 'package:base':
#> 
#>     date
library(ggplot2)
library(tikzDevice)


df <- dplyr::tibble(
  x = as.Date("2017-07-01") - months(0:11),
  y = sample(0:9, 12, replace = TRUE)
)

out_file <- capture.output(
  tikz(console = TRUE, width = 2.5, height = 1),
  plot <- ggplot(df, aes(x, y)) +
    geom_line(size = 3) +
    geom_point() +
    theme_void() +
    theme(legend.position = "none"),
  print(plot),
  dev.off()
)

# tikzDevice output
writeLines(out_file)
#> % Created by tikzDevice version 0.10.1 on 2017-08-15 11:48:28
#> % !TEX encoding = UTF-8 Unicode
#> \relax
#> \begin{tikzpicture}[x=1pt,y=1pt]
#> \definecolor{fillColor}{RGB}{255,255,255}
#> \path[use as bounding box,fill=fillColor,fill opacity=0.00] (0,0) rectangle (180.67, 72.27);
#> \begin{scope}
#> \path[clip] (  2.75,  2.75) rectangle (180.67, 72.27);
#> \definecolor{drawColor}{RGB}{0,0,0}
#> 
#> \path[draw=drawColor,line width= 3.4pt,line join=round] ( 10.84, 21.71) --
#>  ( 25.85, 37.51) --
#>  ( 40.38, 53.31) --
#>  ( 55.39, 69.11) --
#>  ( 69.92, 13.81) --
#>  ( 84.93, 29.61) --
#>  ( 99.95, 69.11) --
#>  (113.51, 61.21) --
#>  (128.52,  5.91) --
#>  (143.05, 21.71) --
#>  (158.06, 53.31) --
#>  (172.59, 69.11);
#> \definecolor{fillColor}{RGB}{0,0,0}
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (172.59, 69.11) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (158.06, 53.31) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (143.05, 21.71) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (128.52,  5.91) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (113.51, 61.21) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 99.95, 69.11) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 84.93, 29.61) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 69.92, 13.81) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 55.39, 69.11) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 40.38, 53.31) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 25.85, 37.51) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 10.84, 21.71) circle (  1.96);
#> \end{scope}
#> \end{tikzpicture}
#> png 
#>   2

# manually trimmed
writeLines(
  out_file[-(c(1:3, 6, 8, (length(out_file) - 1):length(out_file)))]
)
#> \begin{tikzpicture}[x=1pt,y=1pt]
#> \definecolor{fillColor}{RGB}{255,255,255}
#> \begin{scope}
#> \definecolor{drawColor}{RGB}{0,0,0}
#> 
#> \path[draw=drawColor,line width= 3.4pt,line join=round] ( 10.84, 21.71) --
#>  ( 25.85, 37.51) --
#>  ( 40.38, 53.31) --
#>  ( 55.39, 69.11) --
#>  ( 69.92, 13.81) --
#>  ( 84.93, 29.61) --
#>  ( 99.95, 69.11) --
#>  (113.51, 61.21) --
#>  (128.52,  5.91) --
#>  (143.05, 21.71) --
#>  (158.06, 53.31) --
#>  (172.59, 69.11);
#> \definecolor{fillColor}{RGB}{0,0,0}
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (172.59, 69.11) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (158.06, 53.31) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (143.05, 21.71) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (128.52,  5.91) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (113.51, 61.21) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 99.95, 69.11) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 84.93, 29.61) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 69.92, 13.81) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 55.39, 69.11) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 40.38, 53.31) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 25.85, 37.51) circle (  1.96);
#> 
#> \path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 10.84, 21.71) circle (  1.96);
#> \end{scope}
#> \end{tikzpicture}

When rendering a minimal tex with both outputs and adding a frame, we can see the difference in borders.

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{backgrounds}

\begin{document}

% Created by tikzDevice version 0.10.1 on 2017-08-15 11:47:27
% !TEX encoding = UTF-8 Unicode
\relax
\begin{tikzpicture}[framed,x=1pt,y=1pt]
\definecolor{fillColor}{RGB}{255,255,255}
\path[use as bounding box,fill=fillColor,fill opacity=0.00] (0,0) rectangle (180.67, 72.27);
\begin{scope}
\path[clip] (  2.75,  2.75) rectangle (180.67, 72.27);
\definecolor{drawColor}{RGB}{0,0,0}

\path[draw=drawColor,line width= 3.4pt,line join=round] ( 10.84, 37.51) --
	( 25.85,  5.91) --
	( 40.38, 61.21) --
	( 55.39, 29.61) --
	( 69.92, 61.21) --
	( 84.93, 13.81) --
	( 99.95, 13.81) --
	(113.51, 69.11) --
	(128.52, 37.51) --
	(143.05,  5.91) --
	(158.06, 21.71) --
	(172.59, 61.21);
\definecolor{fillColor}{RGB}{0,0,0}

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (172.59, 61.21) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (158.06, 21.71) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (143.05,  5.91) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (128.52, 37.51) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (113.51, 69.11) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 99.95, 13.81) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 84.93, 13.81) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 69.92, 61.21) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 55.39, 29.61) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 40.38, 61.21) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 25.85,  5.91) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 10.84, 37.51) circle (  1.96);
\end{scope}
\end{tikzpicture}
null device
          1
          
\begin{tikzpicture}[framed,x=1pt,y=1pt]
\definecolor{fillColor}{RGB}{255,255,255}
\begin{scope}
\definecolor{drawColor}{RGB}{0,0,0}

\path[draw=drawColor,line width= 3.4pt,line join=round] ( 10.84, 37.51) --
	( 25.85,  5.91) --
	( 40.38, 61.21) --
	( 55.39, 29.61) --
	( 69.92, 61.21) --
	( 84.93, 13.81) --
	( 99.95, 13.81) --
	(113.51, 69.11) --
	(128.52, 37.51) --
	(143.05,  5.91) --
	(158.06, 21.71) --
	(172.59, 61.21);
\definecolor{fillColor}{RGB}{0,0,0}

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (172.59, 61.21) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (158.06, 21.71) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (143.05,  5.91) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (128.52, 37.51) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] (113.51, 69.11) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 99.95, 13.81) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 84.93, 13.81) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 69.92, 61.21) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 55.39, 29.61) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 40.38, 61.21) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 25.85,  5.91) circle (  1.96);

\path[draw=drawColor,line width= 0.4pt,line join=round,line cap=round,fill=fillColor] ( 10.84, 37.51) circle (  1.96);
\end{scope}
\end{tikzpicture}


\end{document}

@krlmlr
Copy link
Collaborator

krlmlr commented Jan 23, 2018

Thanks. I was able to compile your .tex file, after adding to \section{} commands the results look like this:

screenshot from 2018-01-23 13-12-34

I don't see what's wrong with the first plot (that uses use as bounding box), how do the results look like on your system?

@karseneau
Copy link
Author

Yes, I produce the same output. The added margin/white-space in the first (1) result is not desirable, the second (2) is what is required.

@krlmlr
Copy link
Collaborator

krlmlr commented Jan 24, 2018

We have a test suite that contains different plots with different techniques, how would a change affect the output there?

If the plots look "much better" without the use as bounding box, we may add another argument to tikz(), maybe bbox = TRUE. I'd rather not implement this change unconditionally, just to avoid the situation where plots start to look worse. I'm happy to review a pull request, but I won't have the time to implement the change myself.

@rstub
Copy link
Member

rstub commented Mar 1, 2019

I do not think this is an issue with tikzDevize. You are creating a drawing canvas of a certain size and ask ggplot2 to draw onto this canvas. The result produced by tikzDevice has precisely the requested size. However, ggplot2 left more space to the left and right than you would like. It might work out to remove the use as bounding box option, producing a tighter cropping via Tikz. However, the resulting image would no longer have the size you originally requested. That is something I am very hesitant to implement.

Instead, I would suggest to instruct ggplot2 to use the provided space more generously:

library(ggplot2)

df <- dplyr::tibble(
  x = as.Date("2017-07-01") - lubridate::month(0:11),
  y = sample(0:9, 12, replace = TRUE)
)

ggplot(df, aes(x, y)) +
  geom_line(size = 3) +
  geom_point() +
  theme_void() +
  theme(legend.position = "none") +
  theme(axis.title = element_blank())
original
ggplot(df, aes(x, y)) +
  geom_line(size = 3) +
  geom_point() +
  theme_void() +
  theme(legend.position = "none") +
  theme(axis.title = element_blank()) + 
  scale_x_date(expand = c(0.01,0))    # <- new
new

The graph looks different since you did not set the RNG's seed.

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

3 participants