PyPlot.jl icon indicating copy to clipboard operation
PyPlot.jl copied to clipboard

MacOSX backend

Open nfoti opened this issue 11 years ago • 21 comments

Do you think it's possible to support the MacOSX backend?

nfoti avatar Aug 12 '13 22:08 nfoti

This requires fixing framework build issue that is discussed on the mailing list.

ViralBShah avatar Aug 15 '13 07:08 ViralBShah

@ViralBShah, graphics are supported on MacOSX via Qt or Gtk, it is only wx that doesn't work. However, I think @nfoti was referring to matplotlib's "native" MacOSX Cocoa backend. I looked into this, but unfortunately I didn't see any straightforward way to implement the Cocoa event loop from Julia (especially since Cocoa's event-loop routines seem to require Objective C).

stevengj avatar Aug 16 '13 14:08 stevengj

I was referring to the matplotlib's MacOSX backend. If it's a huge pain to implement then it's not a big deal. It just is nicer than QT on OSX.

Thanks.

Sent from my iPhone

On Aug 16, 2013, at 7:10 AM, "Steven G. Johnson" [email protected] wrote:

@ViralBShah, graphics are supported on MacOSX via Qt or Gtk, it is only wx that doesn't work. However, I think @nfoti was referring to matplotlib's "native" MacOSX Cocoa backend. I looked into this, but unfortunately I didn't see any straightforward way to implement the Cocoa event loop from Julia (especially since Cocoa's event-loop routines seem to require Objective C).

— Reply to this email directly or view it on GitHub.

nfoti avatar Aug 16 '13 15:08 nfoti

I agree that it would be nicer, I just can't figure out any way to support its event loop in a non-blocking way. IPython doesn't seem to support it either, probably for the same reason. (@minrk, do you know anything about this?)

stevengj avatar Aug 16 '13 15:08 stevengj

IPython does support the OS X backend. We use a matplotlib Timer object to put our do_one_iteration() inside the Cocoa eventloop. I imagine you could do the same.

minrk avatar Aug 16 '13 17:08 minrk

Hmm, it doesn't really seem acceptable to have Cocoa in charge of the event loop and to call Julia occasionally; it should be the other way around. Otherwise we lose Julia's ability to process other tasks asynchronously. cc: @JeffBezanson

What I looked for, and couldn't find, was some Cocoa function to process pending events and then return, similar to how we handle other toolkits now. Am I missing something?

stevengj avatar Aug 16 '13 17:08 stevengj

@minrk, do you use Timers now instead of the inputhook stuff?

stevengj avatar Aug 16 '13 17:08 stevengj

inputhook is only for single-process terminal IPython - there is no inputhook in the Kernel.

minrk avatar Aug 16 '13 18:08 minrk

What I looked for, and couldn't find, was some Cocoa function to process pending events and then return, similar to how we handle other toolkits now. Am I missing something?

If you find such a thing, it would certainly be preferable to the inversion of priority that IPython does currently.

minrk avatar Aug 16 '13 18:08 minrk

Hmm, it looks like CFRunLoopRunInMode, passing seconds=0.0, might do the trick, i.e. something like:

ccall(:CFRunLoopRunInMode, Int32, (Ptr{Void}, Float64, Uint8), 
      unsafe_load(cglobal(:kCFRunLoopDefaultMode, Ptr{Void})), 0.0, 0)

Doesn't seem to be working though; I must be missing something.

stevengj avatar Aug 20 '13 21:08 stevengj

Even without the official OSX background, is there a way to get this running on OSX? I use Anaconda Python and have tried all sorts of things, but continue to get various errors. If you would like more info, just let me know.

sglyon avatar Aug 20 '13 23:08 sglyon

I run it on MacOS X. If you install things yourself using pip and brew, rather than Anaconda, it works fine. The problem is that Anaconda's qt installation is broken.

Even with Anaconda, it works fine in IJulia for me, thanks to commit 8599ca04986f7962bbdb622aeb9073d34167b7ff

stevengj avatar Aug 21 '13 13:08 stevengj

Thank you @stevengj. I have had problems with Anaconda running some of my PySide applications in the past so I am sure it is related to the broken qt.

I'll try one of my other python environments.

sglyon avatar Aug 21 '13 16:08 sglyon

Not sure if this is still a problem, but upgrading to the latest anaconda version finally allowed me to use PyPlot.

grero avatar Jun 23 '14 07:06 grero

Good to hear, @grero!

stevengj avatar Jun 23 '14 13:06 stevengj

I'm having this issue. I've tried many things with no luck:

  1. I installed Qt and can run matplotlib from python but in Julia, a blank window comes up.
  2. I've tried using GTK but this doesn't even work from Python. It complains that it can't import pygtk. pygtk is installed as pygtk whereas matplotlib tries to import gtk. Changing the name isn't enough: it also tries to access the gdk symbol from gtk module but this doesn't exist in pygtk. There is an older gtk module but macports claims that this is deprecated. I think matplotlib is not up to date or some such.
  3. I've tried installing and running from Anaconda but that doesn't seem to help.

Any help would be greatly appreciated.

kasrllc avatar Jul 07 '14 09:07 kasrllc

For future reference, this discussion (TooTallNate/NodObjC#2) of integrating CFRunLoop with libuv's event loop may be useful.

stevengj avatar Jul 26 '14 17:07 stevengj

Concerning the email exchange below, I'm finally back in a position to work on this. My first inclination after looking at the Julia code is to eliminate the dissonance with libuv by replacing it with the core foundation runloop - or the Cocoa runloop depending on what is needed to make Julia a more MacOS as opposed to a darwin app. There is such a small amount of code that it shouldn't be hard to create a prototype version of Julia.

Steven - if you post or mail me the code you mention on 8/20/13 I'll use that as a test case. It would also better help me understand what is wrong.

Subject: Re: PyPlot and cocoa? From: "Steven G. Johnson" [email protected] Date: July 26, 2014 at 10:17:56 AM PDT To: Stephen Bespalko [email protected]

Stephen,

It would be great to have someone more knowledgeable about the CF event infrastructure take a look at this. However, In general we prefer to have these discussions in public github issues.

Regarding the Julia event loop, as I understand it this is based on the cross-platform libuv asynchronous I/O library. I'm not sure if it is feasible or desirable to have a libuv backend that runs using the Cocoa event loops, but https://github.com/TooTallNate/NodObjC/issues/2 may be relevant. (I've posted a link in PyPlot#11, but discussions of core Julia event-loop changes should occur on the julia-dev list or in a Julia issue.)

(I don't really understand why the solution is not as simple as calling CFRunLoopRunInMode occasionally to process GUI events, similar to how Qt and Gtk are handled, but for some reason Julia doesn't seem to be getting events directed at the window that matplotlib opens.)

On Jul 24, 2014, at 12:47 PM, Stephen Bespalko wrote:

Hi Steven.

After reading the comments on the github Issue 11… I need the capability bad enough that I’m willing to take a run at it - if the fix isn’t already in the works. It seems to me that the problem is that Julia is not a good mac citizen - the PyPlot looks fine to me. Would it be productive to rewrite the Julia event loop code in terms of CF or even cocoa abstractions (for OSX only)? If so, I’ll give it a shot. I’m just not sure how much time I can put into the effort with my other commitments - thus feeling confident that I’m on the path of greatest likelihood of success is enabling.

Sincerely, Stephen Bespalko

protogeezer avatar Nov 12 '14 22:11 protogeezer

The (non-functional) code that I mentioned is in the macos branch of PyCall, and in particular can be found in this commit.

stevengj avatar Nov 12 '14 23:11 stevengj

There is code for making the timer based sharing of a TTY interface and event loop driven (cocoa) GUI in a single thread in the python mac specific folder - it’s similar to what you have in PyCall but I don’t think it’s exactly the same. I can pursue that but I’d also like to discuss the pros and cons of going for a more general solution.

A few caveats - I have had trouble building julia-0.4 which has slowed down figuring out the scope of the issue the PyCall has with the cocoa code/guis. I’m assuming that a similar issue exists with julia directly calling dynamic libraries with GUI code vis-a-vis those referenced through python modules. I also can’t say for sure yet why some of the window managers work with the scheme you’ve implemented. (A guess is that the cocoa code in PyCall may be creating a “nested” event loop that isn’t running). So, I hope I’m not too badly jumping the gun.

If julia could be configured with event loops from a particular window manager, and the input and basic processing implemented with a bit of multi-threading, the combination should eliminate the issues with trying to run julia (and presumably ijulia or python) and a gui in a single thread. I'm willing to prototype a cocoa version of julia to test before the idea is broached to the julia development community. My first thought is to make the OS X configuration of Julia use the corefoundation (nee Cocoa) event loop running in the default thread. To keep that from blocking, monitoring STDIN could be moved to a second thread and Julia itself to a third thread.

The devil is in the details but I don’t see this being a gigantic change.

What do you think?

Stephen

On Nov 12, 2014, at 3:33 PM, Steven G. Johnson [email protected] wrote:

The (non-functional) code that I mentioned is in the macos branch of PyCall, and in particular can be found in stevengj/PyCall.jl@36e4af5.

— Reply to this email directly or view it on GitHub.

protogeezer avatar Nov 24 '14 02:11 protogeezer

If you want to rewrite the event loop of Julia itself, I would discuss it on the julia-dev mailing list; it's not really a PyPlot question.

stevengj avatar Nov 25 '14 00:11 stevengj