Я работаю над созданием pdf-документа, содержащего графики, используя reportlab и matplotlib, и недавно у меня возникла проблема, из-за которой я не могу добиться того, чтобы тиковые метки по оси x соответствовали данным на простой сторонерядом "барный участок.
Документ довольно длинный и сложный, поэтому я вернул его к основам.Надеюсь, Айв сократил это до минимального полного и проверяемого примера.
Мой перегруженный код выглядит следующим образом:
#!/usr/bin/env python3
import numpy as np
import reportlab.lib, reportlab.platypus
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm, inch, cm
from reportlab.pdfgen import canvas
import matplotlib.pyplot as plt
from io import BytesIO
class flowable(reportlab.platypus.Flowable):
def __init__(self, imgdata):
reportlab.platypus.Flowable.__init__(self)
self.img = reportlab.lib.utils.ImageReader(imgdata)
def draw(self):
self.canv.drawImage(self.img, 0, 0, height = -4.5*inch, width=7*inch)
class LetterMaker(object):
""""""
#----------------------------------------------------------------------
def __init__(self, pdf_file):
self.c = canvas.Canvas(pdf_file, pagesize=A4)
self.styles = getSampleStyleSheet()
self.width, self.height = A4
#----------------------------------------------------------------------
def createDocument(self):
""""""
rx = [14, 44, 16, 155, 214, 187, 222, 405, 314, 199]
tx = [56, 92, 103, 28, 22, 12, 24, 75, 20, 15]
dates = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1) # nrows, ncols, index
indices = np.arange(len(dates))
bar_width = np.min(np.diff(indices))/3.
ax.axes.set_xticklabels(labels)
plt.bar(indices-bar_width/2, rx, bar_width)
plt.bar(indices+bar_width/2, tx, bar_width)
imgdata = BytesIO()
fig.savefig(imgdata, format='png', edgecolor='#79b85f', facecolor=fig.get_facecolor())
imgdata.seek(0) # rewind the data
pic = flowable(imgdata)
pic.wrapOn(self.c, self.width, self.height)
pic.drawOn(self.c, *self.coord( 2, 14, cm))
def coord(self, x, y, unit=1):
x, y = x * unit, self.height - y * unit
return x, y
def savePDF(self):
""""""
self.c.save()
if __name__ == "__main__":
doc = LetterMaker("testfile.pdf")
doc.createDocument()
doc.savePDF()
Когда я запускаю этот код, результирующий график выглядит так:
![enter image description here](https://i.stack.imgur.com/C2JiU.png)
Я не могу объяснить, почему метки оси x не соответствуют полному набору согласно списку меток.
Первоначально данные дат были списком целых чисел.
Я подозревалэтот matplotlib пытался быть полезным и подгонял числовые данные к диапазону, но только находил пересечение двух списков, поэтому я представил его в виде списка строк, но проблема сохраняется.
Я посмотрел вокругnet и SO для указателей, но, кажется, не могу найти что-либо непосредственно релевантное.
Я использовал следующие ресурсы в качестве руководства для написания моего кода, а также в качестве помощи по устранению неполадок:
Reportlab:Смешивание фиксированного содержимого и потоковых таблиц
пример кода API: barchart_demo.py
, и я также использовал этот вопрос SO в качестве руководства
Как построить гистограммуs с одинаковыми координатами X рядом («уклонено»)
Может кто-нибудь объяснить, почему это происходит?
РЕДАКТИРОВАТЬ
Согласно комментарию @Пол Х, я убрал код отчета и все еще получаю тот же результат.
Обновленный код следует:
#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np
rx = [14, 44, 16, 155, 214, 187, 222, 405, 314, 199]
tx = [56, 92, 103, 28, 22, 12, 24, 75, 20, 15]
dates = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1) # nrows, ncols, index
indices = np.arange(len(dates))
bar_width = np.min(np.diff(indices))/3.
ax.axes.set_xticklabels(labels)
plt.bar(indices-bar_width/2, rx, bar_width)
plt.bar(indices+bar_width/2, tx, bar_width)
fig.savefig('plot.png')
Результат все тот же.