正如您所建议的那样,可能有一些方法可以使事情与 svg 和一些 javascript 或 pdf 工具提示一起工作(在您提到它们之前我不知道 pdf 工具提示存在!)。
顺便说一句,我应该花点时间提一下mpld3它使用以下命令将 matplotlib 图形重新创建为 javascript 可视化d3
。它确实允许very可共享的交互式图形,并有一些制作交互式工具提示的示例。
但是,我不确定如何使 matplotlib 的 svg 文件通常具有交互性,并且您提到您不想走 javascript 路线,所以我将引导您构建一个“独立”可执行文件(或者更确切地说, ,一个包含可执行文件和关联库的目录)。
使用以下命令构建“独立”可执行文件cx_freeze
and matplotlib
至少在打包可执行文件方面,我建议cx_freeze
。还有很多其他选择(例如pyinstaller
, py2exe
, py2app
等),但大多数都是特定于平台的,对我来说有点太“神奇”了。cx_freeze
需要更多的知识才能使用,但它非常可靠,一旦您知道需要包含哪些内容,使用起来并不难。
首先,我将向您介绍的完整示例可在此处找到:https://gist.github.com/joferkington/9214844它使用您在之前问题中提供的示例脚本和数据。
关键是要建立一个setup.py
正确引用 1) matplotlib 的数据文件和 2) 代码中需要包含的任何数据才能正确运行的文件。
之后,就很简单了python setup.py build_exe
并 tar 它创建的构建目录以发送给其他人。 (您可能想做一些更奇特的事情。可以制作包含 tar 数据、库和可执行文件的 shell 脚本,但我将在这里跳过这一部分。)
制作setup.py
file
与setup.py
。假设您有一个名为的简单脚本plot.py
其中包含一些基本的绘图代码和一个名为data.csv
与您想要绘制的数据matplotlib
等。setup.py
归档cx_freeze
看起来像这样:(另外,为了简单起见,我假设您正在使用 matplotlib 的 Tk 后端。如果您没有使用,情况看起来会略有不同。)
import cx_Freeze
import sys
import matplotlib
base = None
if sys.platform == "win32":
base = "Win32GUI"
executables = [
cx_Freeze.Executable("plot.py", base = base),
]
build_exe_options = {"includes":["matplotlib.backends.backend_tkagg"],
"include_files":[(matplotlib.get_data_path(), "mpl-data"),
('data.csv', 'data.csv')],
"excludes":[],
}
cx_Freeze.setup(
name = "script",
options = {"build_exe": build_exe_options},
version = "0.0",
description = "A basic example",
executables = executables)
其中大部分都是样板文件。关键部分是:
- 您的脚本的名称(
x_Freeze.Executable("plot.py", base = base)
)
- The
"includes"
部分中的build_exe_options
. cx_freeze
会尝试自动猜测它需要包含哪些模块,但在某些情况下不可能检测到它需要的所有模块。此部分允许您指定要显式包含的其他模块。 matplotlib 后端通常无法正确自动检测,因此您需要显式包含您正在使用的后端。
- The
"include_files"
部分中的build_exe_options
。这表示需要包含的任何其他数据文件。 Matplotlib 有一些数据文件(图标等),需要与代码和库一起提供才能正常运行。线路(matplotlib.get_data_path(), "mpl-data")
获取这些文件并将它们放入构建目录中名为“mpl-data”的文件夹中。同样,该行('data.csv', 'data.csv')
获取“data.csv”文件并将其以相同的名称保存在构建目录中。
我会花点时间提一下"excludes"
选项。这完全是可选的,但是cx_freeze
通常会包含许多脚本运行实际上不需要的库。如果您想缩小要分发的文件的大小,您可能需要列出要在此处排除的特定 python 模块。 (例如。"excludes":['PyQt4', 'scipy']
)
其余部分是相当不言自明的。您可能需要填写描述、版本等,但这不是构建可执行文件所必需的。
Building
所以此时,我们有一个内容类似于以下内容的目录:
$ ls
data.csv plot.py setup.py
data.csv
有我们的数据,plot.py
是绘制它的脚本,并且setup.py
如上所述。
要构建可执行文件,我们需要运行
python setup.py build_exe
您将获得很长的构建日志以及它正在复制的内容(可能还有一些在大多数情况下可以安全忽略的警告)。 (这是有用的信息,可用于调试您的问题setup.py
file.)
完成后,您会注意到一个名为的新目录build
.
$ ls
build data.csv plot.py setup.py
在此刻,build
将包含一个名为类似于以下内容的目录:
$ ls build
exe.linux-x86_64-2.7
The exe.whatever
目录包含库、数据和可执行文件,您需要将它们分发给人们才能正确运行。
要查看它是否有效,请尝试(注意明确的cd
进入目录!!稍后会详细介绍。):
$ cd build/exe.linux-x86_64-2.7
$ ./plot
(显然,如果你上面的文件没有被调用plot.py
,可执行文件不会被调用plot
,但你明白了。)
此时,您可以将exe.whatever
目录(可能想在打包之前重命名),将其发送出去,并告诉人们通过解压和调用来运行它cd name_of_dir; ./plot
.
关于数据路径的注意事项
我提到过我们目前需要明确cd
在运行之前进入目录。这纯粹是因为以下事实:plot.py
寻找一个名为data.csv
在当前目录下.
换句话说,有一行plot.py
这样做:
df = pd.read_csv('data.csv', ...)
We made setup.py
足够聪明,可以包括data.csv
但读取它的代码期望它位于当前目录中。
您有两个选择:
- Always
cd
在运行脚本之前进入目录(实际上,发送一个简短的脚本cd
进入,运行程序,并且cd
退出)。如果您不想使用第二个选项,那么这作为最后的手段非常有用。
- 更改代码以引用相对于脚本位置的数据文件。
由于多种原因,第二个选项更好,但您必须修改脚本(plot.py
,在这种情况下)稍微。
通常,您会使用路径__file__
确定相对于脚本本身的位置。然而,随着cx_freeze
, __file__
不会被定义,你想要的路径是sys.executable
反而。因此,您通常会执行以下操作:(来自 cx_freeze 常见问题解答:http://cx-freeze.readthedocs.org/en/latest/faq.html#data-files)
def find_data_file(filename):
if getattr(sys, 'frozen', False):
# The application is frozen
datadir = os.path.dirname(sys.executable)
else:
# The application is not frozen
# Change this bit to match where you store your data files:
datadir = os.path.dirname(__file__)
return os.path.join(datadir, filename)
在这种情况下,您需要修改代码:
pd.read_csv('data.csv', ...)
to do:
pd.read_csv(find_data_file('data.csv'), ...)
反而。 (这在plot.py
文件在g我最初链接到的。我将把它留给读者作为练习。)
一旦我们完成此操作,您就可以致电/path/to/where/the/directory/gets/copied/plot
直接不管当前工作目录是什么。
分发
关于这个话题我不会说太多。有很多方法可以处理这个问题。和cx_freeze
,您正在发送一个充满库和单个可执行文件的文件夹。
在最简单的情况下,您只需将其压缩,然后告诉人们解压并运行where/they/extracted/it/name_of_the_execuctable
。您可能想要将文件夹重命名为exe.linux-x86_64-2.7
更像是my_package
并包含一个名为的 shell 脚本run_this
或其他什么,但这取决于你。
在其他情况下,您可能想要编写一个包装脚本,甚至是一个.desktop
文件。桌面文件必须有绝对路径,因此在这种情况下您需要做更多的事情。通常,您编写某种类型的安装程序脚本来修改whatever.desktop
指向程序安装位置的绝对路径。
可以将压缩后的数据、库和可执行文件嵌入到“自解压”安装脚本中。如果您想深入了解,网上有一些示例。您还可以构建 .rpm 或 .deb。再次,我将跳过详细的示例,并将其留给您来解决。
总的来说,对于您似乎正在做的事情,发送 tarball 和 README 可能是最简单的途径。