Skip to content

Instantly share code, notes, and snippets.

@mathematicalcoffee
Created April 23, 2013 07:12
Show Gist options
  • Save mathematicalcoffee/5441441 to your computer and use it in GitHub Desktop.
Save mathematicalcoffee/5441441 to your computer and use it in GitHub Desktop.
Automatically set knitr's figure caption option to the title of the ggplot in the chunk. The gist has the R code you should put in your document, as well as an example Rmd with the compiled output.
# Include the following in a chunk up the top of your document
# Then in your plot chunk, use 'fig.cap=cap()'.
# Set the title of your ggplot via `labs(title="mytitle")`, and
# it will automatically be substituted into the chunk options
# as 'fig.cap'
library(knitr)
opts_knit$set(eval.after='fig.cap')
cap <- function () {
p <- last_plot()
if (!is.null(p) && !is.null(p$labels$title)) {
paste('Figure:', p$labels$title)
} else {
NULL # null caption
}
}
<!DOCTYPE html>
<!-- saved from url=(0014)about:internet -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>Example of using the autocaption script.</title>
<style type="text/css">
body, td {
font-family: sans-serif;
background-color: white;
font-size: 12px;
margin: 8px;
}
tt, code, pre {
font-family: 'DejaVu Sans Mono', 'Droid Sans Mono', 'Lucida Console', Consolas, Monaco, monospace;
}
h1 {
font-size:2.2em;
}
h2 {
font-size:1.8em;
}
h3 {
font-size:1.4em;
}
h4 {
font-size:1.0em;
}
h5 {
font-size:0.9em;
}
h6 {
font-size:0.8em;
}
a:visited {
color: rgb(50%, 0%, 50%);
}
pre {
margin-top: 0;
max-width: 95%;
border: 1px solid #ccc;
white-space: pre-wrap;
}
pre code {
display: block; padding: 0.5em;
}
code.r, code.cpp {
background-color: #F8F8F8;
}
table, td, th {
border: none;
}
blockquote {
color:#666666;
margin:0;
padding-left: 1em;
border-left: 0.5em #EEE solid;
}
hr {
height: 0px;
border-bottom: none;
border-top-width: thin;
border-top-style: dotted;
border-top-color: #999999;
}
@media print {
* {
background: transparent !important;
color: black !important;
filter:none !important;
-ms-filter: none !important;
}
body {
font-size:12pt;
max-width:100%;
}
a, a:visited {
text-decoration: underline;
}
hr {
visibility: hidden;
page-break-before: always;
}
pre, blockquote {
padding-right: 1em;
page-break-inside: avoid;
}
tr, img {
page-break-inside: avoid;
}
img {
max-width: 100% !important;
}
@page :left {
margin: 15mm 20mm 15mm 10mm;
}
@page :right {
margin: 15mm 10mm 15mm 20mm;
}
p, h2, h3 {
orphans: 3; widows: 3;
}
h2, h3 {
page-break-after: avoid;
}
}
</style>
<!-- Styles for R syntax highlighter -->
<style type="text/css">
pre .operator,
pre .paren {
color: rgb(104, 118, 135)
}
pre .literal {
color: rgb(88, 72, 246)
}
pre .number {
color: rgb(0, 0, 205);
}
pre .comment {
color: rgb(76, 136, 107);
}
pre .keyword {
color: rgb(0, 0, 255);
}
pre .identifier {
color: rgb(0, 0, 0);
}
pre .string {
color: rgb(3, 106, 7);
}
</style>
<!-- R syntax highlighter -->
<script type="text/javascript">
var hljs=new function(){function m(p){return p.replace(/&/gm,"&amp;").replace(/</gm,"&lt;")}function f(r,q,p){return RegExp(q,"m"+(r.cI?"i":"")+(p?"g":""))}function b(r){for(var p=0;p<r.childNodes.length;p++){var q=r.childNodes[p];if(q.nodeName=="CODE"){return q}if(!(q.nodeType==3&&q.nodeValue.match(/\s+/))){break}}}function h(t,s){var p="";for(var r=0;r<t.childNodes.length;r++){if(t.childNodes[r].nodeType==3){var q=t.childNodes[r].nodeValue;if(s){q=q.replace(/\n/g,"")}p+=q}else{if(t.childNodes[r].nodeName=="BR"){p+="\n"}else{p+=h(t.childNodes[r])}}}if(/MSIE [678]/.test(navigator.userAgent)){p=p.replace(/\r/g,"\n")}return p}function a(s){var r=s.className.split(/\s+/);r=r.concat(s.parentNode.className.split(/\s+/));for(var q=0;q<r.length;q++){var p=r[q].replace(/^language-/,"");if(e[p]){return p}}}function c(q){var p=[];(function(s,t){for(var r=0;r<s.childNodes.length;r++){if(s.childNodes[r].nodeType==3){t+=s.childNodes[r].nodeValue.length}else{if(s.childNodes[r].nodeName=="BR"){t+=1}else{if(s.childNodes[r].nodeType==1){p.push({event:"start",offset:t,node:s.childNodes[r]});t=arguments.callee(s.childNodes[r],t);p.push({event:"stop",offset:t,node:s.childNodes[r]})}}}}return t})(q,0);return p}function k(y,w,x){var q=0;var z="";var s=[];function u(){if(y.length&&w.length){if(y[0].offset!=w[0].offset){return(y[0].offset<w[0].offset)?y:w}else{return w[0].event=="start"?y:w}}else{return y.length?y:w}}function t(D){var A="<"+D.nodeName.toLowerCase();for(var B=0;B<D.attributes.length;B++){var C=D.attributes[B];A+=" "+C.nodeName.toLowerCase();if(C.value!==undefined&&C.value!==false&&C.value!==null){A+='="'+m(C.value)+'"'}}return A+">"}while(y.length||w.length){var v=u().splice(0,1)[0];z+=m(x.substr(q,v.offset-q));q=v.offset;if(v.event=="start"){z+=t(v.node);s.push(v.node)}else{if(v.event=="stop"){var p,r=s.length;do{r--;p=s[r];z+=("</"+p.nodeName.toLowerCase()+">")}while(p!=v.node);s.splice(r,1);while(r<s.length){z+=t(s[r]);r++}}}}return z+m(x.substr(q))}function j(){function q(x,y,v){if(x.compiled){return}var u;var s=[];if(x.k){x.lR=f(y,x.l||hljs.IR,true);for(var w in x.k){if(!x.k.hasOwnProperty(w)){continue}if(x.k[w] instanceof Object){u=x.k[w]}else{u=x.k;w="keyword"}for(var r in u){if(!u.hasOwnProperty(r)){continue}x.k[r]=[w,u[r]];s.push(r)}}}if(!v){if(x.bWK){x.b="\\b("+s.join("|")+")\\s"}x.bR=f(y,x.b?x.b:"\\B|\\b");if(!x.e&&!x.eW){x.e="\\B|\\b"}if(x.e){x.eR=f(y,x.e)}}if(x.i){x.iR=f(y,x.i)}if(x.r===undefined){x.r=1}if(!x.c){x.c=[]}x.compiled=true;for(var t=0;t<x.c.length;t++){if(x.c[t]=="self"){x.c[t]=x}q(x.c[t],y,false)}if(x.starts){q(x.starts,y,false)}}for(var p in e){if(!e.hasOwnProperty(p)){continue}q(e[p].dM,e[p],true)}}function d(B,C){if(!j.called){j();j.called=true}function q(r,M){for(var L=0;L<M.c.length;L++){if((M.c[L].bR.exec(r)||[null])[0]==r){return M.c[L]}}}function v(L,r){if(D[L].e&&D[L].eR.test(r)){return 1}if(D[L].eW){var M=v(L-1,r);return M?M+1:0}return 0}function w(r,L){return L.i&&L.iR.test(r)}function K(N,O){var M=[];for(var L=0;L<N.c.length;L++){M.push(N.c[L].b)}var r=D.length-1;do{if(D[r].e){M.push(D[r].e)}r--}while(D[r+1].eW);if(N.i){M.push(N.i)}return f(O,M.join("|"),true)}function p(M,L){var N=D[D.length-1];if(!N.t){N.t=K(N,E)}N.t.lastIndex=L;var r=N.t.exec(M);return r?[M.substr(L,r.index-L),r[0],false]:[M.substr(L),"",true]}function z(N,r){var L=E.cI?r[0].toLowerCase():r[0];var M=N.k[L];if(M&&M instanceof Array){return M}return false}function F(L,P){L=m(L);if(!P.k){return L}var r="";var O=0;P.lR.lastIndex=0;var M=P.lR.exec(L);while(M){r+=L.substr(O,M.index-O);var N=z(P,M);if(N){x+=N[1];r+='<span class="'+N[0]+'">'+M[0]+"</span>"}else{r+=M[0]}O=P.lR.lastIndex;M=P.lR.exec(L)}return r+L.substr(O,L.length-O)}function J(L,M){if(M.sL&&e[M.sL]){var r=d(M.sL,L);x+=r.keyword_count;return r.value}else{return F(L,M)}}function I(M,r){var L=M.cN?'<span class="'+M.cN+'">':"";if(M.rB){y+=L;M.buffer=""}else{if(M.eB){y+=m(r)+L;M.buffer=""}else{y+=L;M.buffer=r}}D.push(M);A+=M.r}function G(N,M,Q){var R=D[D.length-1];if(Q){y+=J(R.buffer+N,R);return false}var P=q(M,R);if(P){y+=J(R.buffer+N,R);I(P,M);return P.rB}var L=v(D.length-1,M);if(L){var O=R.cN?"</span>":"";if(R.rE){y+=J(R.buffer+N,R)+O}else{if(R.eE){y+=J(R.buffer+N,R)+O+m(M)}else{y+=J(R.buffer+N+M,R)+O}}while(L>1){O=D[D.length-2].cN?"</span>":"";y+=O;L--;D.length--}var r=D[D.length-1];D.length--;D[D.length-1].buffer="";if(r.starts){I(r.starts,"")}return R.rE}if(w(M,R)){throw"Illegal"}}var E=e[B];var D=[E.dM];var A=0;var x=0;var y="";try{var s,u=0;E.dM.buffer="";do{s=p(C,u);var t=G(s[0],s[1],s[2]);u+=s[0].length;if(!t){u+=s[1].length}}while(!s[2]);if(D.length>1){throw"Illegal"}return{r:A,keyword_count:x,value:y}}catch(H){if(H=="Illegal"){return{r:0,keyword_count:0,value:m(C)}}else{throw H}}}function g(t){var p={keyword_count:0,r:0,value:m(t)};var r=p;for(var q in e){if(!e.hasOwnProperty(q)){continue}var s=d(q,t);s.language=q;if(s.keyword_count+s.r>r.keyword_count+r.r){r=s}if(s.keyword_count+s.r>p.keyword_count+p.r){r=p;p=s}}if(r.language){p.second_best=r}return p}function i(r,q,p){if(q){r=r.replace(/^((<[^>]+>|\t)+)/gm,function(t,w,v,u){return w.replace(/\t/g,q)})}if(p){r=r.replace(/\n/g,"<br>")}return r}function n(t,w,r){var x=h(t,r);var v=a(t);var y,s;if(v){y=d(v,x)}else{return}var q=c(t);if(q.length){s=document.createElement("pre");s.innerHTML=y.value;y.value=k(q,c(s),x)}y.value=i(y.value,w,r);var u=t.className;if(!u.match("(\\s|^)(language-)?"+v+"(\\s|$)")){u=u?(u+" "+v):v}if(/MSIE [678]/.test(navigator.userAgent)&&t.tagName=="CODE"&&t.parentNode.tagName=="PRE"){s=t.parentNode;var p=document.createElement("div");p.innerHTML="<pre><code>"+y.value+"</code></pre>";t=p.firstChild.firstChild;p.firstChild.cN=s.cN;s.parentNode.replaceChild(p.firstChild,s)}else{t.innerHTML=y.value}t.className=u;t.result={language:v,kw:y.keyword_count,re:y.r};if(y.second_best){t.second_best={language:y.second_best.language,kw:y.second_best.keyword_count,re:y.second_best.r}}}function o(){if(o.called){return}o.called=true;var r=document.getElementsByTagName("pre");for(var p=0;p<r.length;p++){var q=b(r[p]);if(q){n(q,hljs.tabReplace)}}}function l(){if(window.addEventListener){window.addEventListener("DOMContentLoaded",o,false);window.addEventListener("load",o,false)}else{if(window.attachEvent){window.attachEvent("onload",o)}else{window.onload=o}}}var e={};this.LANGUAGES=e;this.highlight=d;this.highlightAuto=g;this.fixMarkup=i;this.highlightBlock=n;this.initHighlighting=o;this.initHighlightingOnLoad=l;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="\\b(0[xX][a-fA-F0-9]+|(\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.ER="(?![\\s\\S])";this.BE={b:"\\\\.",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE],r:0};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.inherit=function(r,s){var p={};for(var q in r){p[q]=r[q]}if(s){for(var q in s){p[q]=s[q]}}return p}}();hljs.LANGUAGES.cpp=function(){var a={keyword:{"false":1,"int":1,"float":1,"while":1,"private":1,"char":1,"catch":1,"export":1,virtual:1,operator:2,sizeof:2,dynamic_cast:2,typedef:2,const_cast:2,"const":1,struct:1,"for":1,static_cast:2,union:1,namespace:1,unsigned:1,"long":1,"throw":1,"volatile":2,"static":1,"protected":1,bool:1,template:1,mutable:1,"if":1,"public":1,friend:2,"do":1,"return":1,"goto":1,auto:1,"void":2,"enum":1,"else":1,"break":1,"new":1,extern:1,using:1,"true":1,"class":1,asm:1,"case":1,typeid:1,"short":1,reinterpret_cast:2,"default":1,"double":1,register:1,explicit:1,signed:1,typename:1,"try":1,"this":1,"switch":1,"continue":1,wchar_t:1,inline:1,"delete":1,alignof:1,char16_t:1,char32_t:1,constexpr:1,decltype:1,noexcept:1,nullptr:1,static_assert:1,thread_local:1,restrict:1,_Bool:1,complex:1},built_in:{std:1,string:1,cin:1,cout:1,cerr:1,clog:1,stringstream:1,istringstream:1,ostringstream:1,auto_ptr:1,deque:1,list:1,queue:1,stack:1,vector:1,map:1,set:1,bitset:1,multiset:1,multimap:1,unordered_set:1,unordered_map:1,unordered_multiset:1,unordered_multimap:1,array:1,shared_ptr:1}};return{dM:{k:a,i:"</",c:[hljs.CLCM,hljs.CBLCLM,hljs.QSM,{cN:"string",b:"'\\\\?.",e:"'",i:"."},{cN:"number",b:"\\b(\\d+(\\.\\d*)?|\\.\\d+)(u|U|l|L|ul|UL|f|F)"},hljs.CNM,{cN:"preprocessor",b:"#",e:"$"},{cN:"stl_container",b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:a,r:10,c:["self"]}]}}}();hljs.LANGUAGES.r={dM:{c:[hljs.HCM,{cN:"number",b:"\\b0[xX][0-9a-fA-F]+[Li]?\\b",e:hljs.IMMEDIATE_RE,r:0},{cN:"number",b:"\\b\\d+(?:[eE][+\\-]?\\d*)?L\\b",e:hljs.IMMEDIATE_RE,r:0},{cN:"number",b:"\\b\\d+\\.(?!\\d)(?:i\\b)?",e:hljs.IMMEDIATE_RE,r:1},{cN:"number",b:"\\b\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",e:hljs.IMMEDIATE_RE,r:0},{cN:"number",b:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",e:hljs.IMMEDIATE_RE,r:1},{cN:"keyword",b:"(?:tryCatch|library|setGeneric|setGroupGeneric)\\b",e:hljs.IMMEDIATE_RE,r:10},{cN:"keyword",b:"\\.\\.\\.",e:hljs.IMMEDIATE_RE,r:10},{cN:"keyword",b:"\\.\\.\\d+(?![\\w.])",e:hljs.IMMEDIATE_RE,r:10},{cN:"keyword",b:"\\b(?:function)",e:hljs.IMMEDIATE_RE,r:2},{cN:"keyword",b:"(?:if|in|break|next|repeat|else|for|return|switch|while|try|stop|warning|require|attach|detach|source|setMethod|setClass)\\b",e:hljs.IMMEDIATE_RE,r:1},{cN:"literal",b:"(?:NA|NA_integer_|NA_real_|NA_character_|NA_complex_)\\b",e:hljs.IMMEDIATE_RE,r:10},{cN:"literal",b:"(?:NULL|TRUE|FALSE|T|F|Inf|NaN)\\b",e:hljs.IMMEDIATE_RE,r:1},{cN:"identifier",b:"[a-zA-Z.][a-zA-Z0-9._]*\\b",e:hljs.IMMEDIATE_RE,r:0},{cN:"operator",b:"<\\-(?!\\s*\\d)",e:hljs.IMMEDIATE_RE,r:2},{cN:"operator",b:"\\->|<\\-",e:hljs.IMMEDIATE_RE,r:1},{cN:"operator",b:"%%|~",e:hljs.IMMEDIATE_RE},{cN:"operator",b:">=|<=|==|!=|\\|\\||&&|=|\\+|\\-|\\*|/|\\^|>|<|!|&|\\||\\$|:",e:hljs.IMMEDIATE_RE,r:0},{cN:"operator",b:"%",e:"%",i:"\\n",r:1},{cN:"identifier",b:"`",e:"`",r:0},{cN:"string",b:'"',e:'"',c:[hljs.BE],r:0},{cN:"string",b:"'",e:"'",c:[hljs.BE],r:0},{cN:"paren",b:"[[({\\])}]",e:hljs.IMMEDIATE_RE,r:0}]}};
hljs.initHighlightingOnLoad();
</script>
<!-- MathJax scripts -->
<script type="text/javascript" src="https://c328740.ssl.cf1.rackcdn.com/mathjax/2.0-latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
</head>
<body>
<h1>Example of using the autocaption script.</h1>
<p>In this document, I create plots with <code>ggplot2</code> and give them titles using <code>labs(title=&quot;...&quot;)</code>.
The autocaption script enables me to set <code>fig.cap=cap()</code> in my chunk options, and the <code>fig.cap</code> option will <em>automatically</em> be set to the title of the ggplot.</p>
<p>Compile it using:</p>
<pre><code class="r">library(knitr)
knit2html(&quot;example.Rmd&quot;)
</code></pre>
<h2>Step 1: include the script</h2>
<p>Include the following chunk in your document.
I recommend setting <code>echo=F</code> so it is hidden, and place it up the top of your document somewhere (before any of your actual chunks).</p>
<pre><code class="r"># This sets up the autocaption script
library(knitr)
opts_knit$set(eval.after = &quot;fig.cap&quot;)
cap &lt;- function() {
p &lt;- last_plot()
if (!is.null(p) &amp;&amp; !is.null(p$labels$title)) {
paste(&quot;Figure:&quot;, p$labels$title)
} else {
NULL # null caption
}
}
</code></pre>
<h2>Step 2: do some plots</h2>
<p>To do some plots you plot as you usually would, except that you put <code>fig.cap=cap()</code> into the chunk options.
For example, the following chunk (without the space between the &#39;{&#39; and the &#39;r&#39;):</p>
<pre><code>```{ r fig.cap=cap()}
library(ggplot2)
ggplot(iris, aes(x=Sepal.Length, y=Petal.Length, colour=Species)) +
geom_point() +
labs(title=&#39;Petal length vs Sepal length&#39;)
```
</code></pre>
<p>produces:</p>
<pre><code class="r">library(ggplot2)
ggplot(iris, aes(x = Sepal.Length, y = Petal.Length, colour = Species)) + geom_point() +
labs(title = &quot;Petal length vs Sepal length&quot;)
</code></pre>
<p><img src="data:image/png;base64,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" alt="Figure: Petal length vs Sepal length"/> </p>
<p>Note that the plot title and figure caption are in sync, and I only had to specify the title in one place (on the plot).
Note - in HTML the alt text is the &ldquo;figure caption&rdquo; (unless you use Pandoc to compile the md to HTML); in LaTeX the caption shows up as a figure caption.
This is the same as if I&#39;d done (without the space between the &#39;{&#39; and the &#39;r&#39;):</p>
<pre><code>```{ r fig.cap=&#39;Petal length vs Sepal length&#39;}
library(ggplot2)
ggplot(iris, aes(x=Sepal.Length, y=Petal.Length, colour=Species)) +
geom_point() +
labs(title=&#39;Petal length vs Sepal length&#39;)
```
</code></pre>
<p>but prevents me from having to type the same title twice.</p>
<h2>Caveats</h2>
<p>There are restrictions on its use:</p>
<ul>
<li>Only works with <code>ggplot2</code> plots, not (say) base graphics</li>
<li>If you have multiple plots in a chunk, they will <em>all</em> get the caption of the last plot of the chunk, so you should only have one plot per chunk.</li>
</ul>
<h2>Conclusion</h2>
<p>Hope you liked it!</p>
</body>
</html>
# Example of using the autocaption script.
In this document, I create plots with `ggplot2` and give them titles using `labs(title="...")`.
The autocaption script enables me to set `fig.cap=cap()` in my chunk options, and the `fig.cap` option will *automatically* be set to the title of the ggplot.
Compile it using:
```{r eval=F}
library(knitr)
knit2html('example.Rmd')
```
## Step 1: include the script
Include the following chunk in your document.
I recommend setting `echo=F` so it is hidden, and place it up the top of your document somewhere (before any of your actual chunks).
```{r autocaption, echo=T}
# This sets up the autocaption script
library(knitr)
opts_knit$set(eval.after='fig.cap')
cap <- function () {
p <- last_plot()
if (!is.null(p) && !is.null(p$labels$title)) {
paste('Figure:', p$labels$title)
} else {
NULL # null caption
}
}
```
## Step 2: do some plots
To do some plots you plot as you usually would, except that you put `fig.cap=cap()` into the chunk options.
For example, the following chunk (without the space between the '{' and the 'r'):
```{ r fig.cap=cap()}
library(ggplot2)
ggplot(iris, aes(x=Sepal.Length, y=Petal.Length, colour=Species)) +
geom_point() +
labs(title='Petal length vs Sepal length')
```
produces:
```{r fig.cap=cap()}
library(ggplot2)
ggplot(iris, aes(x=Sepal.Length, y=Petal.Length, colour=Species)) +
geom_point() +
labs(title='Petal length vs Sepal length')
```
Note that the plot title and figure caption are in sync, and I only had to specify the title in one place (on the plot).
Note - in HTML the alt text is the "figure caption" (unless you use Pandoc to compile the md to HTML); in LaTeX the caption shows up as a figure caption.
This is the same as if I'd done (without the space between the '{' and the 'r'):
```{ r fig.cap='Petal length vs Sepal length'}
library(ggplot2)
ggplot(iris, aes(x=Sepal.Length, y=Petal.Length, colour=Species)) +
geom_point() +
labs(title='Petal length vs Sepal length')
```
but prevents me from having to type the same title twice.
## Caveats
There are restrictions on its use:
* Only works with `ggplot2` plots, not (say) base graphics
* If you have multiple plots in a chunk, they will *all* get the caption of the last plot of the chunk, so you should only have one plot per chunk.
## Conclusion
Hope you liked it!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment