首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在PdfPages页面中添加matplotlib图中的超链接

在PdfPages页面中添加matplotlib图中的超链接
EN

Stack Overflow用户
提问于 2020-03-31 13:42:13
回答 1查看 623关注 0票数 0

我正在使用PdfPages创建多个多页PDF报告,方法是通过一个数据帧运行一个for循环。我已经做好了一切准备,除了我需要包括一些超链接(介于0到3之间),最好是在msr_line4上,但是如果它们需要在单独的线路上,我可以让它工作。

代码语言:javascript
复制
import pandas as pd
import numpy as np
import pickle
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import matplotlib.lines as mlines
from matplotlib.pyplot import figure
from matplotlib.backends.backend_pdf import PdfPages
import seaborn as sns
import matplotlib.image as mpimg
import mpl_toolkits.axisartist as axisartist

## Text

msr_line1 = r'$\bf{' + 'Name: ' + '}$' + 'Calls name from df'
msr_line2 = r'$\bf{' + 'Measure: ' + '}$' + 'Calls measure from df'
msr_line3 = r'$\bf{' + 'Direction: ' + '}$' + 'Calls direction from df'
msr_line4 = r'$\bf{' + 'Link\ to\ Resources: ' + '}$' + "NEED TO INSERT HYPERLINK HERE"

with PdfPages('msr.pdf') as pdf:
    plt.figure(figsize=(11, 8.5))

    ## Header text
    ax2 = plt.subplot2grid((9, 5), (1, 0), rowspan=1, colspan=2)
    ax2.text(0, .9, msr_line1, fontsize=9)
    ax2.text(0, 0.6, msr_line2, fontsize=9)
    ax2.text(0, 0.3, msr_line3, fontsize=9)
    ax2.text(0, 0, msr_line4, fontsize=9)
    plt.axis('off')
    pdf.savefig()
    plt.close

现在正在使用的编辑/更新库:

代码语言:javascript
复制
import pandas as pd
import numpy as np
import pickle
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import matplotlib.lines as mlines
from matplotlib.pyplot import figure
import seaborn as sns
import matplotlib.image as mpimg
import mpl_toolkits.axisartist as axisartist
from matplotlib import rcParams

import matplotlib
matplotlib.use('pgf')
from PyPDF2 import PdfFileMerger
import os

参数:

代码语言:javascript
复制
plt.rc('text', usetex=True)
rcParams['font.family'] = 'serif'
rcParams['font.serif'] = ['Georgia']
plt.rcParams['pgf.preamble'] = [r'\usepackage{hyperref} \hypersetup{hidelinks,' 
                                'colorlinks=true, urlcolor=cyan}', ]

ax2 = plt.subplot2grid((9, 5), (1, 0), rowspan=1, colspan=1)
plt.text(0, .9, msr_line1, fontsize=9)
plt.text(0, 0.6, msr_line2, fontsize=9)
plt.text(0, 0.3, msr_line3, fontsize=9)
plt.text(0, 0, r'\href{https://stackoverflow.com/questions/}{StackOverflow}', fontsize=9)
plt.axis('off')

我现在遇到的错误是:

代码语言:javascript
复制
CalledProcessError                        Traceback (most recent call last)
~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\texmanager.py in _run_checked_subprocess(self, command, tex)
    303                                              cwd=self.texcache,
--> 304                                              stderr=subprocess.STDOUT)
    305         except FileNotFoundError as exc:

~\AppData\Local\Continuum\anaconda3\lib\subprocess.py in check_output(timeout, *popenargs, **kwargs)
    394     return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
--> 395                **kwargs).stdout
    396 

~\AppData\Local\Continuum\anaconda3\lib\subprocess.py in run(input, capture_output, timeout, check, *popenargs, **kwargs)
    486             raise CalledProcessError(retcode, process.args,
--> 487                                      output=stdout, stderr=stderr)
    488     return CompletedProcess(process.args, retcode, stdout, stderr)

CalledProcessError: Command '['latex', '-interaction=nonstopmode', '--halt-on-error', 
'C:\\Users\\KrumlinZ\\.matplotlib\\tex.cache\\2d92c6482fbb9d5f9ece1213452d403d.tex']' returned non-zero exit status 1.

The above exception was the direct cause of the following exception:

RuntimeError                              Traceback (most recent call last)
<ipython-input-13-c8cf5db9d20c> in <module>
    226 
    227     measure_page = str(ProviderNumber) + str(msr) + '_msr.pdf'
--> 228     plt.savefig(measure_page)
    229     merger.append(measure_page)
    230     #os.remove(measure_page)

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\pyplot.py in savefig(*args, **kwargs)
    720 def savefig(*args, **kwargs):
    721     fig = gcf()
--> 722     res = fig.savefig(*args, **kwargs)
    723     fig.canvas.draw_idle()   # need this if 'transparent=True' to reset colors
    724     return res

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\figure.py in savefig(self, fname, transparent, **kwargs)
   2178             self.patch.set_visible(frameon)
   2179 
-> 2180         self.canvas.print_figure(fname, **kwargs)
   2181 
   2182         if frameon:

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\backend_bases.py in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, **kwargs)
   2080                     orientation=orientation,
   2081                     bbox_inches_restore=_bbox_inches_restore,
-> 2082                     **kwargs)
   2083             finally:
   2084                 if bbox_inches and restore_bbox:

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\backends\backend_pdf.py in print_pdf(self, filename, dpi, bbox_inches_restore, metadata, **kwargs)
   2501                 RendererPdf(file, dpi, height, width),
   2502                 bbox_inches_restore=bbox_inches_restore)
-> 2503             self.figure.draw(renderer)
   2504             renderer.finalize()
   2505             if not isinstance(filename, PdfPages):

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
     36                 renderer.start_filter()
     37 
---> 38             return draw(artist, renderer, *args, **kwargs)
     39         finally:
     40             if artist.get_agg_filter() is not None:

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\figure.py in draw(self, renderer)
   1707             self.patch.draw(renderer)
   1708             mimage._draw_list_compositing_images(
-> 1709                 renderer, self, artists, self.suppressComposite)
   1710 
   1711             renderer.close_group('figure')

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\image.py in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    133     if not_composite or not has_images:
    134         for a in artists:
--> 135             a.draw(renderer)
    136     else:
    137         # Composite any adjacent images together

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
     36                 renderer.start_filter()
     37 
---> 38             return draw(artist, renderer, *args, **kwargs)
     39         finally:
     40             if artist.get_agg_filter() is not None:

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\axes\_base.py in draw(self, renderer, inframe)
   2645             renderer.stop_rasterizing()
   2646 
-> 2647         mimage._draw_list_compositing_images(renderer, self, artists)
   2648 
   2649         renderer.close_group('axes')

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\image.py in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    133     if not_composite or not has_images:
    134         for a in artists:
--> 135             a.draw(renderer)
    136     else:
    137         # Composite any adjacent images together

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
     36                 renderer.start_filter()
     37 
---> 38             return draw(artist, renderer, *args, **kwargs)
     39         finally:
     40             if artist.get_agg_filter() is not None:

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\text.py in draw(self, renderer)
    668 
    669         with _wrap_text(self) as textobj:
--> 670             bbox, info, descent = textobj._get_layout(renderer)
    671             trans = textobj.get_transform()
    672 

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\text.py in _get_layout(self, renderer)
    296             if clean_line:
    297                 w, h, d = renderer.get_text_width_height_descent(
--> 298                     clean_line, self._fontproperties, ismath=ismath)
    299             else:
    300                 w = h = d = 0

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\backends\_backend_pdf_ps.py in get_text_width_height_descent(self, s, prop, ismath)
     45             fontsize = prop.get_size_in_points()
     46             w, h, d = texmanager.get_text_width_height_descent(
---> 47                 s, fontsize, renderer=self)
     48             return w, h, d
     49         elif ismath:

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\texmanager.py in get_text_width_height_descent(self, tex, fontsize, renderer)
    446         else:
    447             # use dviread. It sometimes returns a wrong descent.
--> 448             dvifile = self.make_dvi(tex, fontsize)
    449             with dviread.Dvi(dvifile, 72 * dpi_fraction) as dvi:
    450                 page, = dvi

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\texmanager.py in make_dvi(self, tex, fontsize)
    336                 self._run_checked_subprocess(
    337                     ["latex", "-interaction=nonstopmode", "--halt-on-error",
--> 338                      texfile], tex)
    339             for fname in glob.glob(basefile + '*'):
    340                 if not fname.endswith(('dvi', 'tex')):

~\AppData\Local\Continuum\anaconda3\lib\site-packages\matplotlib\texmanager.py in _run_checked_subprocess(self, command, tex)
    315                     prog=command[0],
    316                     tex=tex.encode('unicode_escape'),
--> 317                     exc=exc.output.decode('utf-8'))) from exc
    318         _log.debug(report)
    319         return report

RuntimeError: latex was not able to process the following string:
b'\\\\href{https://stackoverflow.com/questions/}{StackOverflow}'

Here is the full report generated by latex:
This is pdfTeX, Version 3.14159265-2.6-1.40.20 (MiKTeX 2.9.7250 64-bit)
entering extended mode
(C:/Users/KrumlinZ/.matplotlib/tex.cache/2d92c6482fbb9d5f9ece1213452d403d.tex
LaTeX2e <2019-10-01> patch level 3

("C:\Users\KrumlinZ\AppData\Local\Programs\MiKTeX 2.9\tex/latex/base\article.cl
s"
Document Class: article 2019/10/25 v1.4k Standard LaTeX document class
("C:\Users\KrumlinZ\AppData\Local\Programs\MiKTeX 2.9\tex/latex/base\size10.clo
"))
("C:\Users\KrumlinZ\AppData\Local\Programs\MiKTeX 2.9\tex/latex/type1cm\type1cm
.sty")
("C:\Users\KrumlinZ\AppData\Local\Programs\MiKTeX 2.9\tex/latex/base\textcomp.s
ty"
("C:\Users\KrumlinZ\AppData\Local\Programs\MiKTeX 2.9\tex/latex/base\ts1enc.def
"
("C:\Users\KrumlinZ\AppData\Local\Programs\MiKTeX 2.9\tex/latex/base\ts1enc.dfu
")))
("C:\Users\KrumlinZ\AppData\Local\Programs\MiKTeX 2.9\tex/latex/base\inputenc.s
ty")
("C:\Users\KrumlinZ\AppData\Local\Programs\MiKTeX 2.9\tex/latex/geometry\geomet
ry.sty"
("C:\Users\KrumlinZ\AppData\Local\Programs\MiKTeX 2.9\tex/latex/graphics\keyval
.sty")
("C:\Users\KrumlinZ\AppData\Local\Programs\MiKTeX 2.9\tex/generic/iftex\ifvtex.
sty"
("C:\Users\KrumlinZ\AppData\Local\Programs\MiKTeX 2.9\tex/generic/iftex\iftex.s
ty"))
("C:\Users\KrumlinZ\AppData\Local\Programs\MiKTeX 2.9\tex/latex/geometry\geomet
ry.cfg")

Package geometry Warning: Over-specification in `h'-direction.
    `width' (5058.9pt) is ignored.


Package geometry Warning: Over-specification in `v'-direction.
    `height' (5058.9pt) is ignored.

) (2d92c6482fbb9d5f9ece1213452d403d.aux)
("C:\Users\KrumlinZ\AppData\Local\Programs\MiKTeX 2.9\tex/latex/base\ts1cmr.fd"
)
*geometry* driver: auto-detecting
*geometry* detected driver: dvips
! Undefined control sequence.
l.14 ...tsize{9.000000}{11.250000}{\rmfamily \href
                                                  {https://stackoverflow.com...
No pages of output.
Transcript written on 2d92c6482fbb9d5f9ece1213452d403d.log.


Error in callback <function install_repl_displayhook.<locals>.post_execute at 0x000001EAC6E4CA68> (for post_execute):
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-01 11:16:12

您将需要使用LaTex和PGF来完成这一任务(除非输出SVG是一个选项)。这需要安装LaTex (TexLive、MikTex等)。不幸的是,这与PdfPages后端不兼容。但是,您可以很容易地将输出PDF连接起来。

下面是一个有用的例子:

代码语言:javascript
复制
import matplotlib
matplotlib.use('pgf')
import matplotlib.pyplot as plt
from PyPDF2 import PdfFileMerger
import os

plt.rc('text', usetex=True)
plt.rc('font', family='serif')
plt.rcParams['pgf.preamble'] = [r'\usepackage{hyperref} \hypersetup{hidelinks,' 
                                'colorlinks=true, urlcolor=cyan}', ]

merger = PdfFileMerger()
for i in range(5):
    plt.figure()
    plt.text(0.5, 0.5, 
             r'\href{https://stackoverflow.com/questions/}{StackOverflow '+str(i)+'}')

    out = './out.'+str(i)+'.pdf'
    plt.savefig(out)
    merger.append(out)
    os.remove(out)

merger.write('./out.pdf')
merger.close()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60952034

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档