簡體   English   中英

在 PdfPages 頁面 Python 內的 matplotlib 圖中添加超鏈接

[英]Add a hyperlink in a matplotlib plot inside a PdfPages page Python

我通過在數據幀中運行 for 循環來使用 PdfPages 創建多個多頁 PDF 報告。 我已經准備好了一切,除了我需要包含一些超鏈接(0 到 3 之間),最好在 msr_line4 上,但如果它們需要在單獨的行上,我可以完成這項工作。

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

現在正在使用編輯/更新庫:

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

參數:

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')

我現在得到的錯誤是:

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):

您將需要使用 LaTex 和 PGF 來完成此操作(除非可以選擇輸出 SVG)。 這將需要安裝 LaTex(TexLive、MikTex 等)。 不幸的是,這與PdfPages后端不兼容。 但是,您可以相當輕松地即時連接輸出 PDF。

這是一個工作示例:

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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM