gregsexton / ob-ipython

org-babel integration with Jupyter for evaluation of (Python by default) code blocks
737 stars 111 forks source link

emacs 26.1 matplotlib problem #180

Closed simonpintarelli closed 6 years ago

simonpintarelli commented 6 years ago

It appears that there is a problem with ob-ipython and Emacs 26.1. ipython blocks that should produce a matplotlib figure hang upon execution. There is a png created, but nothing written to it. Downgrading to Emacs 25.3 fixes the issue.

dangirsh commented 6 years ago

This is preventing me from using Emacs 26. Added a small bounty.

For compiler flag reference:

Works with Emacs 25.3.1:

Hangs on png save with Emacs 26.1:

Not that it should matter, but I run Emacs 25 natively on Ubuntu 16.04, and Emacs 26 in here: https://github.com/JAremko/docker-emacs/blob/master/Dockerfile.emacs26

nicolaroberto-tesla commented 6 years ago

I am sorry, not reproducible for me on:

GNU Emacs 26.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.30) of 2018-05-29

It works like a charm.

I had a similar problem (and now I cannot remember the details) but it was related more to matplotlib rather than ob-ipython.

Cheers.

fuxialexander commented 6 years ago

Also not reproducible on Emacs 27 for me.

simonpintarelli commented 6 years ago

I can reproduce it, for example with the following code:

#+BEGIN_SRC ipython :session :ipyfile test.png :exports both :results raw drawer
  %matplotlib inline
  from matplotlib.pyplot import *
  import numpy as np

  x = np.linspace(0, 1, 100)
  plot(x, x)
#+END_SRC

The process hangs during writing test.png and consumes 100% CPU, when I press Ctrl-g it asks to kill the image buffer, if I say no, I can find the correct plot in the buffer test.png. When I switch to this buffer and call save-buffer it will hang again consuming 100% cpu.

Version: GNU Emacs 26.1 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.30) of 2018-05-29 Matplotlib (python3) 2.2.2 default matplotlibrc configuration: https://gist.github.com/simonpp/b1ff8f973d722d613dedaeb7c73411db

I've tried changing matplotlib backends, and using svg instead of png, but it didn't help.

@nicolaroberto-tesla Could you share the relevant parts of your matplotlibrc?

nicolaroberto-tesla commented 6 years ago

Hi,

@simonpp

I pasted your last snipped of code in the scratch buffer and it works. It outputs a png that I can open.

I do not use a matplotlibrc, frankly it is the first time I hear of its existence.

Normally, I use the following code to setup matplotlib:

  import IPython
  from tabulate import tabulate

  class OrgFormatter(IPython.core.formatters.BaseFormatter):
      def __call__(self, obj):
          try:
              return tabulate(obj, headers='keys',
                              tablefmt='orgtbl', showindex='always')
          except:
              return None

  ip = get_ipython()
  ip.display_formatter.formatters['text/org'] = OrgFormatter()

  import matplotlib
  %matplotlib inline
  %config InlineBackend.figure_format = 'svg'
  matplotlib.rc('font', family='Arial')
  import matplotlib.pyplot as plt
  import numpy as np
  from IPython.display import set_matplotlib_formats
  matplotlib.rcParams['axes.unicode_minus'] = False
  set_matplotlib_formats('svg', 'pdf')

I hope it helps,

Cheers

simonpintarelli commented 6 years ago

Hi,

it seems thatdelete-trailing-whitespace is responsible for this issue. When I remove it from the before-save-hook everything works fine.

@nicolaroberto-tesla thank you for pasting the code!

Cheers

simonpintarelli commented 6 years ago

@gregsexton

It hangs during write-file when delete-trailing-whitespace is contained in the before-save-hook, the following workaround fixes the problem for me.

;; in ob-ipython.el
(defun ob-ipython--write-base64-string (file b64-string)
  (if b64-string
      (with-temp-buffer
        (let ((buffer-file-coding-system 'binary)
              (require-final-newline nil)
              (before-save-hook nil))
          (insert b64-string)
          (base64-decode-region (point-min) (point-max))
          (write-file file)))
    (error "No output was produced to write to a file.")))