Comparte la imagen de mpldatacursor con otros

Estoy usando el ejemplo en Cómo mostrar tags de datos cuando pasas el mouse sobre los datos para hacer una imagen donde aparecen los datos cuando pasas el mouse sobre los puntos. Esto funciona realmente bien, pero ¿hay alguna forma de guardarlo para que pueda enviar la imagen a otros? No estoy seguro de qué formatos son compatibles con “información sobre herramientas”, pero ambos, pdf y svg, ¿y quizás hay alguna otra forma?

Si necesito empaquetar el ejecutable, ¿cuál es la forma más sencilla de hacerlo en Linux?

Puede haber formas de hacer que las cosas funcionen con svg y un poco de información sobre herramientas de javascript o pdf, como usted sugirió (¡No sabía que existía información sobre herramientas de pdf hasta que las mencionó!).

Dejando de lado, debo tomarme un momento para mencionar mpld3 que recrea las figuras de matplotlib como visualizaciones de javascript usando d3 . Permite figuras muy compartibles e interactivas y tiene algunos ejemplos de cómo hacer información sobre herramientas interactiva.

Sin embargo, no estoy seguro de cómo hacer que los archivos svg de matplotlib sean generalmente interactivos, y mencionó que preferiría no ir por la ruta de javascript, así que lo guiaré a través de la construcción de un ejecutable “independiente” (o , un directorio con un ejecutable y bibliotecas asociadas).

Construyendo un ejecutable “independiente” con cx_freeze y matplotlib

Al menos con respecto al empaquetado de un ejecutable, recomendaría cx_freeze . Hay muchas otras opciones (por ejemplo, pyinstaller , py2exe , py2app , etc.), pero la mayoría de ellas son específicas de la plataforma y un poco “mágicas” para mi gusto. cx_freeze requiere un poco más de conocimiento para usar, pero es bastante confiable, y no es tan difícil de usar una vez que esté al tanto de lo que debe incluirse.

En primer lugar, el ejemplo completo que estoy a punto de mostrarle está disponible aquí: https://gist.github.com/joferkington/9214844 Utiliza un script de ejemplo y los datos que proporcionó como parte de una pregunta anterior.

La clave es crear un archivo setup.py que haga referencia correctamente a 1) los archivos de datos de matplotlib y 2) cualquier información que necesite incluir con su código para que se ejecute correctamente.

Después de eso, es tan simple como python setup.py build_exe y tar el directorio de comstackción que crea para enviar a otras personas. (Es probable que desee hacer algo un poco más sofisticado. Es posible crear scripts de shell que contengan los datos, bibliotecas y archivos ejecutables, pero omitiré esa parte aquí).

Haciendo el archivo setup.py

Encendido con el setup.py . Supongamos que tiene un script simple llamado plot.py que contiene un código de trazado básico y un archivo llamado data.csv con los datos que desea trazar con matplotlib , etc. El archivo cx_freeze para cx_freeze se vería así: (Además, para simplificar, asumo que estás usando el back-end Tk para matplotlib. Las cosas se verán ligeramente diferentes si no lo estás).

 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) 

La mayor parte de esto es repetitivo. Las partes clave son:

  1. El nombre de su script ( x_Freeze.Executable("plot.py", base = base) )
  2. La sección "includes" en las build_exe_options . cx_freeze intentará adivinar automáticamente qué módulos debe incluir, pero hay casos en los que no es posible detectar todo lo que necesita. Esta sección le permite especificar módulos adicionales para incluir explícitamente. Los backends de matplotlib generalmente no se detectan automáticamente, por lo que deberá incluir explícitamente el backend que esté usando.
  3. La sección "include_files" en build_exe_options . Esto indica cualquier archivo de datos adicional que deba incluirse. Matplotlib tiene algunos archivos de datos (íconos, etc.) que deben enviarse junto con el código y las bibliotecas para que las cosas funcionen correctamente. La línea (matplotlib.get_data_path(), "mpl-data") obtiene estos archivos y los coloca en una carpeta llamada “mpl-data” dentro del directorio de comstackción. De manera similar, la línea ('data.csv', 'data.csv') obtiene su archivo “data.csv” y lo guarda con el mismo nombre en el directorio de comstackción.

Me tomaré un segundo para mencionar la opción "excludes" . Esto es completamente opcional, pero cx_freeze usualmente incluirá muchas bibliotecas que no son realmente necesarias para que su script funcione. Si desea reducir el tamaño del archivo que está distribuyendo, es posible que desee enumerar los módulos de Python particulares para excluir aquí. (por ejemplo, "excludes":['PyQt4', 'scipy'] )

El rest es bastante autoexplicativo. Es posible que desee completar la descripción, la versión, etc., pero no es necesario comstackr un ejecutable.

edificio

Entonces, en este punto, tenemos un directorio con contenidos similares a los siguientes:

 $ ls data.csv plot.py setup.py 

data.csv tiene nuestros datos, plot.py es el script para setup.py , y setup.py es como se describe anteriormente.

Para construir un ejecutable, corríamos

 python setup.py build_exe 

Obtendrá un registro largo de la comstackción y exactamente sobre lo que se está copiando (probablemente junto con algunas advertencias que pueden ignorarse de forma segura en la mayoría de los casos). (Esta es información útil para depurar lo que está mal con su archivo setup.py ).

Una vez que se complete, notará un nuevo directorio llamado build .

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

En este punto, la build contendrá un solo directorio llamado algo similar a:

 $ ls build exe.linux-x86_64-2.7 

El directorio exe.whatever contiene las bibliotecas, los datos y el ejecutable que deberá distribuir a las personas para que las cosas se ejecuten correctamente.

Para ver si funciona, intente (¡anote el cd explícito en el directorio! Más sobre esto en un momento):

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

(Obviamente, si su archivo de arriba no se llamó plot.py , el ejecutable no se llamará plot , pero se le plot.py la idea).

En este punto, usted podría abrir el directorio exe.whatever (probablemente quiera cambiarle el nombre antes de ponerle espuma), enviarlo, y decirle a la gente que lo ejecute sin marcar y llamando a cd name_of_dir; ./plot cd name_of_dir; ./plot .

Advertencias sobre los caminos a los datos

Mencioné que actualmente debemos incluir explícitamente el cd en el directorio antes de ejecutar las cosas. Esto es plot.py el resultado del hecho de que plot.py busca un archivo llamado data.csv en el directorio actual .

En otras palabras, hay una línea en plot.py que hace:

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

Hicimos que setup.py suficientemente inteligente como para incluir data.csv pero el código que lo lee espera que esté en el directorio actual.

Tienes dos opciones:

  1. cd siempre en el directorio antes de ejecutar el script (en la práctica, envíe un script corto que cd s, ejecute el progtwig y cd s vuelva a ejecutarse). Esto es útil como último recurso si no quiere molestarse con la segunda opción.
  2. Cambie su código para hacer referencia al archivo de datos relativo a la ubicación del script.

La segunda opción es mejor por varias razones, pero tendrá que modificar su script ( plot.py , en este caso) ligeramente.

Normalmente, usaría la ruta de acceso a __file__ para determinar la ubicación relativa al script en sí. Sin embargo, con cx_freeze , __file__ no se definirá, y la ruta que desea es la de sys.executable . Por esa razón, normalmente haces algo como esto: (De las preguntas frecuentes de 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) 

En ese caso, modificarías tu código que hace:

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

que hacer:

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

en lugar. (Esto no se ha hecho en el archivo plot.py en la plot.py a la que he vinculado originalmente . Se lo dejaré al lector como un ejercicio).

Una vez que hayamos hecho eso, puede llamar /path/to/where/the/directory/gets/copied/plot directamente sin importar cuál es el directorio de trabajo actual.

Distribuido

No voy a decir mucho sobre este tema. Hay muchas maneras de manejar esto. Con cx_freeze , estás enviando una carpeta llena de bibliotecas y un solo ejecutable.

En el caso más simple, solo lo haces, y le dices a la gente que lo descomprima y ejecute where/they/extracted/it/name_of_the_execuctable . Es posible que desee cambiar el nombre de la carpeta de exe.linux-x86_64-2.7 a algo más como my_package e incluir un script de shell llamado run_this o algo así, pero eso depende de usted.

En otros casos, es posible que desee escribir un script de envoltorio o incluso un archivo .desktop . Los archivos de escritorio deben tener rutas absolutas, por lo que deberá hacer un poco más en ese caso. Por lo general, usted escribe un script de instalación de algún tipo que modifique whatever.desktop que sea.desktop para que apunte a la ruta absoluta donde se instala su progtwig.

Es posible incrustar los datos, bibliotecas y archivos ejecutables en un script de instalación “autoextraíble”. Hay ejemplos en la web si quieres buscarlos. También puedes construir un .rpm o .deb. Una vez más, me saltaré el ejemplo detallado y te lo dejaré para que lo averigües.

En general, para lo que parece estar haciendo, enviar un archivo tar y un README es probablemente la ruta más simple.