【问题标题】:Share image from mpldatacursor with others与他人共享来自 mpldatacursor 的图像
【发布时间】:2014-03-28 02:17:03
【问题描述】:

我正在使用How to show data labels when you mouse over data 的示例制作图像,当您将鼠标悬停在点上时会出现数据。这确实很好,但是有什么方法可以保存它,以便我可以将图像发送给其他人?我不确定哪些格式支持“工具提示”,但 pdf 和 svg 都支持,也许还有其他方式?

如果我需要打包可执行文件,在 linux 中最简单的方法是什么?

【问题讨论】:

    标签: python pdf svg matplotlib


    【解决方案1】:

    按照您的建议,可能有一些方法可以使用 svg 和一些 javascript 或 pdf 工具提示(在您提到它们之前我不知道存在 pdf 工具提示!)。

    顺便说一句,我应该花点时间提到mpld3,它使用d3 将matplotlib 图形重新创建为javascript 可视化。它确实允许非常可共享的交互式图形,并提供了一些制作交互式工具提示的示例。

    但是,我不确定如何使 matplotlib 的 svg 文件具有一般交互性,并且您提到您不想走 javascript 路线,所以我将引导您构建一个“独立”可执行文件(或者,更确切地说,一个包含可执行文件和相关库的目录)。

    使用cx_freezematplotlib 构建“独立”可执行文件

    至少在打包可执行文件方面,我推荐cx_freeze。还有很多其他选项(例如pyinstallerpy2exepy2app 等),但其中大多数都是特定于平台的,对我的口味来说有点“神奇”。 cx_freeze 需要更多的知识才能使用,但它非常可靠,一旦您知道需要包含哪些内容,使用起来也不会太难。

    首先,我将向您介绍的完整示例可在此处获得:https://gist.github.com/joferkington/9214844 它使用您在之前的问题中提供的示例脚本和数据。

    关键是构建一个setup.py 文件,该文件正确引用 1) matplotlib 的数据文件和 2) 您需要包含在代码中以使其正确运行的任何数据。

    之后,就像python setup.py build_exe 一样简单,然后将它创建的构建目录 tar 发送给其他人。 (您可能想做一些更花哨的事情。可以制作包含 tar 数据、库和可执行文件的 shell 脚本,但我将在此处跳过该部分。)

    制作setup.py 文件

    使用setup.py。假设您有一个名为 plot.py 的简单脚本,其中包含一些基本的绘图代码和一个名为 data.csv 的文件,其中包含您要使用 matplotlib 绘制的数据等。setup.py 文件为 cx_freeze 看起来像这样的东西:(另外,为简单起见,我假设您将 Tk 后端用于 matplotlib。如果您不使用,情况看起来会略有不同。)

    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)
    

    其中大部分是样板文件。关键部分是:

    1. 脚本的名称 (x_Freeze.Executable("plot.py", base = base))
    2. build_exe_options 中的"includes" 部分。 cx_freeze 将尝试自动猜测它需要包含哪些模块,但在某些情况下无法检测到它需要的所有模块。本节允许您指定要显式包含的其他模块。 matplotlib 后端通常无法正确自动检测,因此您需要明确包含您正在使用的任何后端。
    3. build_exe_options 中的"include_files" 部分。这表示需要包含的任何其他数据文件。 Matplotlib 有一些数据文件(图标等)需要与代码和库一起提供才能正常运行。 (matplotlib.get_data_path(), "mpl-data") 行获取这些文件并将它们放在构建目录中名为“mpl-data”的文件夹中。同样,('data.csv', 'data.csv') 行获取您的“data.csv”文件并将其以相同的名称保存在构建目录中。

    我会花一点时间来提一下"excludes" 选项。这完全是可选的,但cx_freeze 通常会包含许多脚本运行实际上并不需要的库。如果您想缩小要分发的文件的大小,您可能需要在此处列出要排除的特定 python 模块。 (例如"excludes":['PyQt4', 'scipy']

    其余的都是不言自明的。您可能需要填写描述、版本等,但构建可执行文件不需要。

    建筑

    所以此时,我们有一个目录,内容类似如下:

    $ ls
    data.csv  plot.py  setup.py
    

    data.csv 有我们的数据,plot.py 是绘制它的脚本,setup.py 如上所述。

    要构建一个可执行文件,我们会运行

    python setup.py build_exe
    

    您会得到一个很长的构建日志以及它正在复制的确切内容(可能还有一些在大多数情况下可以安全忽略的警告)。 (这是调试setup.py 文件问题的有用信息。)

    完成后,您会注意到一个名为 build 的新目录。

    $ ls
    build  data.csv  plot.py  setup.py
    

    此时,build 将包含一个目录,其名称类似于:

    $ ls build
    exe.linux-x86_64-2.7
    

    exe.whatever 目录包含库、数据和可执行文件,您需要将它们分发给人们以使事情正常运行。

    要查看它是否有效,请尝试(注意目录中的显式cd!稍后会详细介绍。):

    $ cd build/exe.linux-x86_64-2.7
    $ ./plot
    

    (很明显,如果你上面的文件没有被称为plot.py,那么可执行文件就不会被称为plot,但你明白了。)

    此时,您可以将 exe.whatever 目录 tar (可能希望在 tar 之前重命名它),将其发送出去,然后通过解压缩并调用 cd name_of_dir; ./plot 来告诉人们运行它。

    关于数据路径的注意事项

    我提到我们目前需要在运行之前明确地将cd 放入目录中。这纯粹是因为plot.py 在当前目录中寻找一个名为data.csv 的文件

    换句话说,plot.py 中有一行:

    df = pd.read_csv('data.csv', ...)
    

    我们使setup.py 足够聪明,可以包含data.csv,但读取它的代码预计它位于当前目录中。

    你有两个选择:

    1. 在运行脚本之前始终将cd 放入目录中(实际上,发送一个简短的脚本,cds 进入,运行程序,cds 退出)。如果您不想为第二个选项烦恼,这可作为最后的手段。
    2. 更改代码以引用相对于脚本位置的数据文件。

    出于多种原因,第二个选项更好,但您必须稍微修改您的脚本(在本例中为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', ...)
    

    要做的事情:

    pd.read_csv(find_data_file('data.csv'), ...) 
    

    相反。 (这在 gist I linked to originally 中的 plot.py 文件中尚未完成。我将把它留给读者作为练习。)

    完成后,无论当前工作目录是什么,您都可以直接调用/path/to/where/the/directory/gets/copied/plot

    分发

    我不会在这个话题上说太多。有很多方法可以处理这个问题。使用cx_freeze,您将发送一个包含库和单个可执行文件的文件夹。

    在最简单的情况下,您只需将其 tar,然后告诉人们解压缩并运行 where/they/extracted/it/name_of_the_execuctable。您可能希望将文件夹从 exe.linux-x86_64-2.7 重命名为类似于 my_package 的名称,并包含一个名为 run_this 的 shell 脚本或其他名称,但这取决于您。

    在其他情况下,您可能想要编写一个包装脚本,甚至是一个.desktop 文件。桌面文件必须有绝对路径,所以在这种情况下你需要做更多的事情。通常,您编写某种安装程序脚本,修改 whatever.desktop 以指向您的程序安装位置的绝对路径。

    可以将压缩后的数据、库和可执行文件嵌入到“自解压”安装脚本中。如果您想四处寻找它们,则网络上有一些示例。您还可以构建一个 .rpm 或 .deb。同样,我将跳过详细的示例,让您自己弄清楚。

    总体而言,对于您似乎正在做的事情,发送 tarball 和 README 可能是最简单的途径。

    【讨论】:

    • 谢谢你。我会尽快尝试。如果有一些简单的方法来使用 mpld3 那就太好了。
    猜你喜欢
    • 2020-02-14
    • 1970-01-01
    • 2023-04-03
    • 2022-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-15
    • 1970-01-01
    相关资源
    最近更新 更多