【问题标题】:How to export text annotations with links using plotly python?如何使用 plotly python 导出带有链接的文本注释?
【发布时间】:2021-12-27 08:36:24
【问题描述】:

我正在使用 python plotly '5.1.0' 来绘制气泡图。 我想做的是还添加一些包含网页链接的文本注释。当我在 jupyter notebook 中显示图形时,一切正常,但是我没有设法将带有工作链接的绘图保存为图片(我最喜欢的格式是 pdf,但我基本上尝试了所有可用的格式)。

这可能与情节?是否有其他库可以实现这一目标?

编辑:最终目标是使用乳胶将图片插入到pdf中,因此首选与此用法直接兼容的解决方案:)

这里使用相同的玩具代码来重现该行为:

import plotly.express as px
df = px.data.gapminder()

fig = px.scatter(df.query("year==2007"), x="gdpPercap", y="lifeExp",
                 size="pop", color="continent",
                 hover_name="country", log_x=True, size_max=60)
fig.add_annotation(text="""here is my <a href="https://rdcu.be/cB1Ds"><b>paper</b></a>""", x=4, y=50)
fig.show()

结果正确显示了一个可点击的链接:

但是,当我保存它时,链接消失了:

fig.write_image("fig1.pdf", engine="kaleido") # I also tried "orca" but doesn't help

【问题讨论】:

  • 试试这个:fig.write_html('./data/file_text.html') 如果你把链接保存成html格式,格式还是有效的。
  • 谢谢@r-beginners,我忘了提到我想将保存的图片包含在pdf文档中。据我所知,不可能将 HTML 图形直接插入到 Latex 中。我认为可能的解决方法可能是this,但我仍然需要尝试。所以我暂时保留这个问题,看看是否有直接的解决方案,谢谢:)
  • 你检查过this similar question吗?
  • 谢谢@KateOrlova,不,我没看过。如果我理解正确,这建议将绘图保存为 HTML 文件,然后使用 Wea​​syPrint 将其呈现为 pdf,对吗?无论如何,在该问题中如何进行转换的实际步骤非常模糊,并且没有将答案作为解决方案进行检查。你能指导我更多吗?

标签: python plotly plotly-python


【解决方案1】:

似乎可用的解决方案并不总是可信的。这也许可以解释为什么没有标准的。我正要建议@rosa b. 的确切解决方案,但当我试图在我的最后复制它时它对我不起作用。可能是因为我使用了具有挑战性的svg 示例,其中包含两种不同类型的超链接:一种围绕形状,另一种围绕文本,以涵盖所有可能性,如下所示:

links.svg

<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> 
 <!-- A link around a shape -->
 <a href="http://www.example.com">
   <circle cx="50" cy="40" r="35" stroke="green" fill="red"/>
     <text x="50" y="40" text-anchor="middle" font-size="0.5em">
       www.example.com
     </text>
 </a>

 <!-- A link around a text -->
 <a href="http://www.foo.bar">
   <text x="50" y="90" text-anchor="middle">
     Foo.Bar
   </text>
 </a>
</svg>

当我执行rosa b.的解决方案时,在Windows环境下使用以下命令:

inkscape.com --export-area-drawing --export-type="pdf" --export-filename=links.pdf --export-latex links.svg

它确实生成了一个links.tex_pdf 文件,该文件也没有正确包含指向文本超链接的链接,建议使用\href{} 手动添加它。

我尝试了另一种解决方案,即使用 Google Chrome 将 svg 打印到 pdf,因为许多 PDF 转换器会将这些超链接过滤为不需要的注释。打印必须没有页眉或页脚,并且边距为 0。这使csv 的超链接保持不变。现在面临第二个挑战,将这个好的 pdf 包含到 LaTeX 中,因为 LaTeX 包含 pdf 再次过滤注释!

我了解了一个名为 pax 的包,您可以将其包含在内以更好地添加带有链接的 pdfs。我听从了他们的建议,最终得到了以下结果:

links.tex

\documentclass[a4paper,12pt,landscape]{article}
\usepackage{hyperref}
\usepackage{pdfpages}
% pdfpages loads graphicx

\usepackage{pax}

\iffalse
  \usepackage{hyperref}
  \hypersetup{
    filebordercolor={1 1 0},
  }
\fi

\begin{document}
  \includepdf[pages=-]{links}
\end{document}

我使用在线 LaTex 编辑器 Overleaf here 试了一下,现在我们在圆圈内得到了可点击的文本,但不是在外面。

我希望这个对您特定的svg 有用。

【讨论】:

  • 感谢 Bilal,非常感谢您在调查中所做的努力!老实说,我不明白您是如何创建 SVG 文件的(我假设您使用的是“HTML 语言”),无论如何我可以看到背面项目中的 links.pdf 实际上有两个链接(我下载并使用 @ 打开它987654343@ 在ubuntu 20.04 系统上)。但是,当我编译项目时,它们都没有在生成的 pdf 中工作。您是否使用了任何特殊的编译选项? (我有一个专业订阅,以防它可能相关......)
  • svg 格式可以使用任何现代浏览器查看。从技术上讲,如果您从&lt;svg&gt; ... &lt;/svg&gt; 中分离出文本部分并将其保存为.svg 文件,那么您将获得独立的图形文件。我使用Chrome 打开文件,然后打印到pdfSave as pdf 选项)。由于您正在操作Ubuntu,我猜Firefox 也可以打印到pdf。我没有为 pdf 使用任何编译选项。
  • 分享您如何生成LaTeX 文档会很有用。你用什么引擎?它使您的情况大不相同。例如Overleaf 能够呈现其中一个超链接,而您的却无法编译任何超链接。也许如果你愿意分享你的 LaTeX 渲染引擎,我们可以更好地研究如何让它表现得更好。
  • 这是一个生动的例子,展示了不同平台的渲染有何不同。下载pdf 后,我可以点击顶部链接,但不能点击底部链接。我想到了一个想法,付诸实施是痛苦的,但却是确定的。如何将现有的pdf 更改为LaTeX,然后将其包含在所需的LaTex 中?这将非常具有挑战性,但实际上可能会奏效。
  • 我不知道这是可能的,我在this 之后尝试了一下,但暂时没有成功。不幸的是,赏金即将到期,所以我必须决定将其授予谁......你的帮助很宝贵,我也学到了很多东西,但是@rosa b.的简短回答是我能做到的最接近的找到一个解决方案(至少在我的平台上),尽管不完全是我所希望的。无论如何感谢@Bilal Quandeel,非常感谢您的帮助! :D
【解决方案2】:

简答

虽然不优雅,但我建议创建一个没有链接的图像,然后使用tikzhyperref 在乳胶中手动将链接添加到图像:

\documentclass{article}
\usepackage{tikz}
\usepackage{hyperref}
\begin{document}

\begin{tikzpicture}
\begin{scope}
    \node[anchor=south west,inner sep=0] (image) at (0,0){\includegraphics[width=0.7\textwidth]{scatter_without_link.png}};
\begin{scope}[x={(image.south east)},y={(image.north west)}]
    \node [anchor=west] (note) at (0.6,0.70) {\href{https://stackoverflow.com}{Link}};
\end{scope}
\end{scope}
\end{tikzpicture}

\end{document}

长答案

您可以创建带有可点击链接的 svg。使用matplotlib 的最小工作示例是

import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.scatter([1, 2, 3], [4, 5, 6])
text = ax.annotate("Link", xy=(2,5), xytext=(2.2,5.5),
                url='https://stackoverflow.com', 
                bbox=dict(color='w', alpha=1e-6, url='https://stackoverflow.com'))
fig.savefig('scatter.svg')

然后将 svg 转换为 pdf,例如使用inkscape 和命令行:

inkscape -D --export-type="pdf" scatter.svg --export-latex

这会生成带有散点图和可点击超链接的 pdf。

但是:在将 pdf 嵌入到您的乳胶文件中时保留超链接(例如,使用 svg package 或简单地使用 \input{scatter.pdf_tex})是一个更困难的问题,因为 pdftex 似乎从包含文件(请参阅这个 10 年前的问题 How to preserve hyperlinks in included PDF?)。

注意:如果您想使用 svg 包,请确保 (1) Inkscape 已安装并在系统路径上,并且 (2) Latex 使用 shell-escape (--shell-escape) 运行已启用。

注 2:用于在 jupyter notebook 中显示 matplotlib 示例:

%config InlineBackend.figure_formats = ['svg']
import matplotlib.pyplot as plt
%matplotlib inline
fig, ax = plt.subplots()
ax.scatter([1, 2, 3], [4, 5, 6])
text = ax.annotate("Link", ... )  # same as above
plt.plot()

【讨论】:

  • 抱歉 matplotlib 示例(不是绘图专家)。另外:很高兴听到是否有人找到了在保留超链接的同时包含 svg/pdf 的解决方案!
  • 非常感谢!我尝试了长答案,但它似乎对我不起作用,因为我在 plt 预览和保存的文件中都看不到可点击的链接......我需要一些特定的 matplotlib 设置或其他包吗?跨度>
  • 感谢您的反馈。超链接是标准的 matplotlib 功能,因此不需要额外的包 (link)。很难说为什么这个例子不适合你。我又试了一次,对我来说,在浏览器中打开文件 scatter.svg 并在 jupyter notebook 中显示该图会产生一个带有可点击链接的散点图(在示例中名为“链接”)。我将在答案中添加 jupyter notebook 代码(尽管还有其他方法可以预览 svg 文件)。
  • 奇怪...代码中没有什么特别的...注释和超链接都可用于早期的matplotlib版本(我使用python 3.8.8和matplotlib 3.4.3)
  • 您使用哪个 Inkscape 版本?如果尚未使用它,您应该考虑升级到 1.+ 版本。关于命令行参数有一些重大变化......或者,您可以使用 Inkscape gui:打开一个新文档并使用 file &gt; open 打开 .svg。然后使用file &gt; save as 并选择pdf 格式将图像保存为pdf。这应该可以工作(使用 Inkscape v1.1 测试)。
猜你喜欢
  • 2018-12-29
  • 1970-01-01
  • 2017-10-17
  • 1970-01-01
  • 2010-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-22
相关资源
最近更新 更多