A while ago I uploaded a document Using Python and matplotlib to create profile graphs and recently there was a question about how to create a PDF with multiple graphs on a single page. In this case I am taking it a little step further and will create a multi page PDF file that will contain 6 graphs on each page base on a combination of suggestions made at this page: matplotlib - Python saving multiple figures into one PDF file - Stack Overflow .
This is what I came up with:
When using subplots, it is important to specify the correct value for rows, cols and plot number. On line 22 you can see the number "321". This represents 3 rows, 2 columns and plot number is 1 (the first one). For every chunk of 100 data points a graph is created and each graph should have its correct plot number, which is why the plot number is incremented for each chunk of 100 data points (line 42).
The chunk size "600" on line 21 in combination with the smaller chunks created on line 24 generate 6 graphs, which correspond to the value 321, where 3 * 2 + results in 6 graphs.
import matplotlib.backends.backend_pdf
import matplotlib.pyplot as plt
import random
def chunks(l, n):
"""Yield successive n-sized chunks from l."""
for i in range(0, len(l), n):
yield l[i:i + n]
# settings
out_pdf = r'C:\GeoNet\Profiles2PDF\test3.pdf'
# some random data
data = []
for i in range(0, 5000):
data.append([i, float(i + random.randrange(-50, 50))/100, 5])
pdf = matplotlib.backends.backend_pdf.PdfPages(out_pdf)
cnt = 0
figs = plt.figure()
for data_chunk in chunks(data, 600):
plot_num = 321
fig = plt.figure(figsize=(10, 10)) # inches
for sub_chunk in chunks(data_chunk, 100):
cnt += 1
d = [a[0] for a in sub_chunk]
z = [a[1] for a in sub_chunk]
zv = [a[2] for a in sub_chunk]
print plot_num
plt.subplot(plot_num)
# plot profile, define styles
plt.plot(d,z,'r',linewidth=0.75)
plt.plot(d,z,'ro',alpha=0.3, markersize=3)
plt.plot(d,zv,'k--',linewidth=0.5)
plt.xlabel('Distance from start')
plt.ylabel('Elevation')
plt.title('Profile {0} using Python matplotlib'.format(cnt))
# change font size
plt.rcParams.update({'font.size': 8})
plot_num += 1
pdf.savefig(fig)
pdf.close()
See below an extract from the resulting PDF file:
In case you want to implement this for elevation data and chunks of 100 meter from a line, you can use Polyline::segmentAlongLine to get the chunks for each graph and Polyline::positionAlongLine to get each individual point on each segment.
Very helpfull, thanks!
Hi! Unfortunately is the code only available as one line of code. I would really like to try out your code. What should one give in the function for l and n?