-
-
Notifications
You must be signed in to change notification settings - Fork 878
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
[Issue 2116] - New chunk option to add separators to subfloat environment #2140
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've reverted some unnecessary changes. The main thing left for this PR is to allow fig.subsep
to be a vector as requested/suggested in #2116 (comment). Are you able to do that? If not, I can ask someone else to do it. BTW, this new feature needs to be mentioned in NEWS.md
, too. Thanks!
Hey! Thank you for the comments and fixes! I read the issue again, and, I will think about this code again to come up with a solution. And how should I fill the |
I added new changes to the code. Now, the option As an example, the following chunk: #| echo = FALSE,
#| fig.cap='Many plots',
#| fig.subcap=c('First plot', 'Second plot', 'Third plot'),
#| out.width='.49\\linewidth',
#| fig.subsep = '\\hfill'
plot(1:10)
plot(rnorm(10), pch=19)
plot(1:5) will produce the same output as the first version of this PR. As a result, this Latex code will be produced: \begin{knitrout}
\definecolor{shadecolor}{rgb}{0.969, 0.969, 0.969}\color{fgcolor}\begin{figure}
\subfloat[First plot\label{fig:pressure-1}]{\includegraphics[width=.49\linewidth]{figure/pressure-1} }
\hfill
\subfloat[Second plot\label{fig:pressure-2}]{\includegraphics[width=.49\linewidth]{figure/pressure-2} }
\hfill
\subfloat[Third plot\label{fig:pressure-3}]{\includegraphics[width=.49\linewidth]{figure/pressure-3} }\caption[Many plots]{Many plots}\label{fig:pressure}
\end{figure}
\end{knitrout} Now, if #| echo = FALSE,
#| fig.cap='Many plots',
#| fig.subcap=c('First plot', 'Second plot', 'Third plot'),
#| out.width='.49\\linewidth',
#| fig.subsep = c('\\prefix', '\\hfill', '\\postfix')
plot(1:10)
plot(rnorm(10), pch=19)
plot(1:5) Then, the first element will be interpreted as the prefix of all subfloats, and the third element, as the postfix of all subfloats. The second element will be "filler", or, the separator between each "inner" subfloat. To be more precise, the above chunk will produce this Latex code: \begin{knitrout}
\definecolor{shadecolor}{rgb}{0.969, 0.969, 0.969}\color{fgcolor}\begin{figure}
\prefix
\subfloat[First plot\label{fig:pressure-1}]{\includegraphics[width=.49\linewidth]{figure/pressure-1} }
\hfill
\subfloat[Second plot\label{fig:pressure-2}]{\includegraphics[width=.49\linewidth]{figure/pressure-2} }
\hfill
\subfloat[Third plot\label{fig:pressure-3}]{\includegraphics[width=.49\linewidth]{figure/pressure-3} }
\postfix
\caption[Many plots]{Many plots}\label{fig:pressure}
\end{figure}
\end{knitrout} I think this is a useful design for this chunk option, because the user can (if he wants to) use the three element vector, and, still, supress some of the separators, by using an empty string. For example, if I want to just prefix all the subfloats, and, not include any other Latex command, I can do this: #| echo = FALSE,
#| fig.cap='Many plots',
#| fig.subcap=c('First plot', 'Second plot', 'Third plot'),
#| out.width='.49\\linewidth',
#| fig.subsep = c('\\prefix', '', '')
plot(1:10)
plot(rnorm(10), pch=19)
plot(1:5) This would produce this Latex code: \begin{knitrout}
\definecolor{shadecolor}{rgb}{0.969, 0.969, 0.969}\color{fgcolor}\begin{figure}
\prefix
\subfloat[First plot\label{fig:pressure-1}]{\includegraphics[width=.49\linewidth]{figure/pressure-1} }
\subfloat[Second plot\label{fig:pressure-2}]{\includegraphics[width=.49\linewidth]{figure/pressure-2} }
\subfloat[Third plot\label{fig:pressure-3}]{\includegraphics[width=.49\linewidth]{figure/pressure-3} }
\caption[Many plots]{Many plots}\label{fig:pressure}
\end{figure}
\end{knitrout} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't look at the code carefully, but I thought we should recycle subsep
by subsep = rep(subsep, length.out = fig.num - 1)
instead of limiting its length to 1 or 3?
Hey @yihui ! Sorry for the delay, I was on vacation. About this question of yours, I am not sure why you would use I did limit Thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @yihui ! Sorry for the delay, I was on vacation.
No worries! I think that was more responsive than me :)
About this question of yours, I am not sure why you would use
rep()
on this situation. Could you elaborate why you would use it?
Sorry I didn't read the original request carefully. Now I understand why the length can be 1 or 3.
I was thinking of making it possible to specify different separators between subfloats, e.g., \hfill
between the first and second plot, and something else between the second and third plot. Perhaps we should use different chunk options to specify the separators before and after all plots (fig.subsep1
and fig.subsep2
?), and use fig.subsep
only in-between plots.
Uhmm! I see what you meant now. I think we can add some changes for this, and, I think the code would be actually simpler than this 1 or 3 length style. I will look into it tomorrow. Bye ✌ |
From the user perspective, I would like something like the following.
The alternative is to have fig.subsep.inner as a recycled vector of inner separators and fig.subsep.outer as a string or one or two-element vector of outer separators. If it is a string or a vector of length one, the element is added before and after all the subfigures. The first option is more comfortable to use, the other seems to be easier to explain and to understand for the new users. I think knitr's usage and its users may be more suitable for the first option. |
I added a new strategy in the code for #| echo = FALSE,
#| fig.cap='Many plots',
#| fig.subcap=c('First plot', 'Second plot', 'Third plot'),
#| out.width='.49\\linewidth',
#| fig.subsep = '\\hfill'
plot(1:10)
plot(rnorm(10), pch=19)
plot(1:5) Would result in the following Latex code: \begin{knitrout}
\definecolor{shadecolor}{rgb}{0.969, 0.969, 0.969}\color{fgcolor}\begin{figure}
\subfloat[First plot\label{fig:pressure-1}]{\includegraphics[width=.49\linewidth]{figure/pressure-1} }
\hfill
\subfloat[Second plot\label{fig:pressure-2}]{\includegraphics[width=.49\linewidth]{figure/pressure-2} }
\hfill
\subfloat[Third plot\label{fig:pressure-3}]{\includegraphics[width=.49\linewidth]{figure/pressure-3} }\caption[Many plots]{Many plots}\label{fig:pressure}
\end{figure}
\end{knitrout} In the other hand, now, with the new version of the code, #| fig.subcap=c('First plot', 'Second plot', 'Third plot'),
#| fig.subsep = c('\\sep1', '\\sep2', '\\sep3')
plot(1:10) #plotA
plot(1:10) #plotB
plot(1:10) #plotC This would result in a Latex code similar to this:
Now, if #| echo = FALSE,
#| fig.cap='Many plots',
#| fig.subcap=c('First plot', 'Second plot', 'Third plot'),
#| out.width='.49\\linewidth',
#| fig.subsep = c('\\firstsep', '\\secondsep', '\\thirdsep', '\\fourthsep')
plot(1:10)
plot(rnorm(10), pch=19)
plot(1:5) Would result in this Latex code: \begin{knitrout}
\definecolor{shadecolor}{rgb}{0.969, 0.969, 0.969}\color{fgcolor}\begin{figure}
\firstsep
\subfloat[First plot\label{fig:pressure-1}]{\includegraphics[width=.49\linewidth]{figure/pressure-1} }
\secondsep
\subfloat[Second plot\label{fig:pressure-2}]{\includegraphics[width=.49\linewidth]{figure/pressure-2} }
\thirdsep
\subfloat[Third plot\label{fig:pressure-3}]{\includegraphics[width=.49\linewidth]{figure/pressure-3} }
\fourthsep\caption[Many plots]{Many plots}\label{fig:pressure}
\end{figure}
\end{knitrout} What do you think about this solution? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This solution sounds good to me. Thank you!
R/hooks-latex.R
Outdated
|
||
# If user provides a vector with `fig.num - 1` or `fig.num` elements, use this case: | ||
if (n_subsep %in% (fig.num + -1:0)) { | ||
sub1 = paste(subsep[fig.cur], sub1, sep = '\n') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is buggy when n_subsep == fig.num - 1
, because fig.cur
ranges from 1
to fig.num
(when fig.cur == fig.num
, subsep[fig.cur]
will be out of bound). For this case, we should conditionally add subsep
to sub1
when !plot1
. I've fixed the problem in my changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made a few tweaks to your code. I hope they make sense and actually work as expected. I'll merge this PR for now. If you have time, I'd truly appreciate it if you could help test the dev version. Thank you very much!
This PR contains a small change to the
hook_plot_tex()
function. This change adds a new chunk option calledfig.subfigsep
. This new chunk option expects to receive a Latex command as a character string (e.g. "\hfill"):The separator will be added to all the plots in the chunk, except the first in the set.