figure caption centering in nbconvert?

2019-04-16 17:21发布

问题:

I have cells underneath figures in an ipython notebook that contain figure caption text. I would like them to be centre('center')-aligned. I use "< center >" in the markdown, which gives exactly the appearance I'm after in the notebook. But when nb-converting to latex, the text gets shunted over to the left.

So is there a way to get nbconvert to recognize text alignment in markdown cells when converting to latex?

Thanks.

回答1:

You have actually asked two different questions:

  1. is there a way to get nbconvert to recognize text alignment in markdown cells
  2. figure caption (centering) in nbconvert

ad 1)
To convert the markdown to latex pandoc is used. Unfortunately, pandoc removes raw html from markdown if converted to latex (if also removes raw latex when converting markdown to html). So it is not that straight forward to use html tags to format the output in both html and latex. This formatting may be achieved based cell metadata but that is not that trivial currently.

ad 2)
Nevertheless it is possible to create caption like text to work with html and latex. Here we have to distinguish between caption for pyout or stream data (e.g. Ipython.display.Image) and markdown images.

pyout and stream

A possible approach is to create a Caption class like

class Caption():
    def __init__(self,s):
        self.s = s
    def _repr_html_(self):
        return '<center>{0}</center>'.format(self.s)
    def _repr_latex_(self):
        return '\\begin{center}\n'+self.s+'\n\\end{center}'

which is called after the image. Note that both should be called with the IPython.display.display method, e.g as oneliner

display(Image('image.jpg'),Caption('Figure Caption'))

This approach allows process the captiontext with python, e.g. to add figure numbers.
If you want to add such a caption to a matplotlib plot, it is a bit more tricky as the wrong ordering has to be overcome. A possible approach is to plot using this snippet

%matplotlib inline
plt.plot([1,2])
f=plt.gcf()
plt.close()
display(f,Caption('Plot'))

It may be noted the the default latex template of IPython 1.x doesn't play well with this approach, as here, image and caption are only loosely coupled and thus, vertical space might be included during latex compiling. The latex_basic template works much better. In IPython master the default templates are working fine.

markdown images

Markdown allows to use images like

![Caption](/files/image)

When converting to latex pandoc can take the Caption part and create a real latex caption. Similar, when converting to html the caption gets embedded in a caption class to be easily styleable using css. However, currently IPython requires a "/files/" prefix which is currently not removed, thus the image file won't be found by latex. (Fixed by now)
Be aware that these markdown image calls do not embed but only link the image into the ipynb file, therefore, the image has to remain available.