I was trying to put a summary of the data under its figure. However, since the length of the summary text varies, it is hard to keep the textbox and the figure vertically aligned (more specifically, the textbox and the figure should have the same width). Is there any way to do this?
-
You may have tripped over some odd matplotlib terminology -- what is a figure in a research paper is usually an `axes` in matplotlib, and a `figure` in matplotlib is more like the page the `axes` and its helpers are printed on. I've answered the question I think you were asking, that is, how to generate a plot and its long explanatory caption together. – cphlewis Feb 27 '20 at 23:42
2 Answers
You can try to do a subplot right below the figure. This guarantees that the width will be the same:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(1, 10, 50)
y = np.sin(x)
plt.subplot(2,1,1)
plt.plot(x,y)
plt.subplot(2,1,2)
description = '''
Sin Function:
In the figure avobe we see how the sin function oscillates and behaves
between 0 and 10
'''
plt.text(0.5, 0.5, description, va='top', ha='center')
plt.axis('off')
plt.show()
However, I am afraid you'll have to insert the line breaks yourself as matplotlib doesn't support text wrapping. Here there's something you can try though.

- 1,265
- 1
- 11
- 13
Yes. You can put a long summary of the plot under the plot. Technically the caption doesn't go into the axes
object, it goes into the figure
object that the axes
was created in, but the reader can't tell that.
Here I estimate the length of a long caption and then add the needed vertical space to the figure
in which the axes
object plots. With some rough calculations of text size, this makes room for matplotlib
's text wrapping to fit very long captions below a figure:
import matplotlib.pyplot as plt
t = "A point is that which has no part. A line is breadthless length. The ends of a line are points. A straight line is a line which lies evenly with the points on itself. A surface is that which has length and breadth only. The edges of a surface are lines. A plane surface is a surface which lies evenly with the straight lines on itself. A plane angle is the inclination to one another of two lines in a plane which meet one another and do not lie in a straight line. "
#t = 3*t
AestheticFigWidth = 6.4
AestheticPlotHeight = 2.4
# 12pt fonts should be 6 lines per vertical inch.
# Very rough estimate of 10 12pt characters per horizontal inch -- it varies!
# Calculate how many more inches of fig you need for your caption,
# add extra for whitespace and labels:
CaptionHeight = (len(t)/(6 * (AestheticFigWidth * 10))) + 0.5
fig = plt.figure(figsize=(AestheticFigWidth,
AestheticPlotHeight + CaptionHeight))
CaptionProportion = CaptionHeight / (AestheticPlotHeight + CaptionHeight)
ax = fig.add_axes((.1, #location proportional to figure
CaptionProportion + .03,
.85, # size proportional to figure
.85 - CaptionProportion))
fig.suptitle("Make space for a big caption")
ax.plot([1,2,3,4,5], [0,5,1,8,0], 'o-')
ax.set_ylabel('Angle')
ax.set_xlabel("Let's not overlap this")
fig.text(.05,.03, t, ha='left', rotation=0, wrap=True, fontsize=12)
plt.show()
With a middling caption:
If you need something more elegant or automatic, I recommend generating the plots in matplotlib and then generating a template in LaTeX to pick up the plots and their captions.

- 15,759
- 4
- 46
- 55