Save as png in google Colab

Hello All!
I am using google colab for rendering some plots through Bokeh. I am getting this error.
RuntimeError: PhantomJS is not present in PATH or BOKEH_PHANTOMJS_PATH. Try “conda install phantomjs” or “npm install -g phantomjs-prebuilt”

I installed PhantomJS. But that didn’t solve the problem . Anybody faced similar issue?

If you have installed it then it got installed some place Bokeh does now know to look for. You can set the environment variable BOKEH_PHANTOMJS_PATH to explicitly point to the location of the phantomjs binary.

Thanks! set the environment variable pointing to PhantomJS binary location like this
os.environ[‘BOKEH_PHANTOMJS_PATH’] = “/usr/local/lib/python3.6/dist-packages/”

Doesnt seem to solve the problem. Am I doing something wrong here?

It should be the full path to the phantomjs executable (wherever that is).

THanks Bryan! But this didnt help.

Any other experts who can help or have any other ideas?

This error is weird, the file gets saved through the tools on the plot. Export Png doesnt seem to work? Any workaround available to invoke from tool?

The SaveTool and export_png do not share anything in common. The save tool generates a data URL directly from the HTML canvas. The Python export functions use a Selenium webdriver to drive a headless browser to generate the image to save. Are you sure you are giving the correct full path to the phantomjs executable binary? To be explicit, the required path ends in “phantomjs”, and is not a directory. Are you actually able to run the phantomjs program yourself? E.g. what is the output of phantomjs --version? If that does not work, then that is the problem (but that is a problem outside Bokeh).

Otherwise, all I can suggest is that you pass use the low level function with a webdriver you create and configure manually.

Something like (untested)

from selenium import webdriver
from bokeh.io.export import get_screenshot_as_png
from bokeh.resources import INLINE

driver = webdriver.PhantomJS(executable_path="/full/path/to/phantomjs")
get_screenshot_as_png(plot, driver=driver, resources=INLINE)

Any workaround available to invoke from tool?

I mean, in principle, but you would need a working Selenium and a headless webdriver to do it, and that is already the issue.

I’ll just state that it’s also entirely possible that there are simply limitations on colab that are out of our control. E.g. push_notebook does not work on colab because colab blocks the necessary websocket APIs. Apparently that restriction has finally been lifted after several years, so that we can maybe make push_notebook work in the near future. But I can’t say what other differences and inconsistencies there are with standard notebooks, that might affect other things.

Beyond all that: Bokeh 2.x uses Chome or FF headless instead of PhantomJS (since PhantomJS is a dead and abandoned project and Selenium 4.0 will drop all support for it). You could see if you have better luck with that. Or you can try installing phantomjs using some different method (e.g. conda-forge instead of pkgs/main, or npm install instead of conda). But the bottom line is that Bokeh actually does almost no actual work here itself, except to create a webdriver and have it load a page. But it has to be possible to create a working webdriver, full stop. If the webdriver can’t initialize, that’s ultimately a function of the local environent, and outside Bokeh’s control.

I see. Thanks for your inputs. Looks like phantomjs command itself is not working. But I do see the folder in the installed location. In between when I change the environment variable to this path, it said unable to access that file. Which means its installing but local environment is not able to access it. Tried with Jupyter notebooks as well. same issue.

Its sad now that I have to switch to Matplotlib as that is the only place where export is working.

Looks like phantomjs command itself is not working.

What exactly does this mean? Is there an error message? What precise steps did you actually take?

Tried with Jupyter notebooks as well. same issue.

In general, export works perfectly well in local Jupyter notebooks:

I’m happy to continue to assist trying to find out what is going on in your specific situation. But it would help very much if you could be much more explicit about exactly what steps you try, and exactly what the results are. E.g. things like “I tried chaging the path and it did not work” is not enough information to go on. What exact path, how exactly did it not work?

Did you try any of the alternate installation methods I suggested? For that matter, how did you install in the first place (you’ve never stated)?

1 Like

Installing phantomjs this way:

!npm install phantomjs-prebuilt

and using the exact reported path reported in the output:

Done. Phantomjs binary available at /content/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs

like this:

import os
os.environ['BOKEH_PHANTOMJS_PATH'] = "/content/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs"

works on colab for me:

All OSS maintainers want their users to succeed. In the spirit of constructive feedback I’d like to share what was frustrating about this exchange for me:

  • I suggested several different things to try
  • You never really said which (if any) you tried
  • And if you did, never said what the actual exact result was

There are far more users than maintainers. In the grand scheme, OSS can only possibly work if you help us help you, e.g. by not being circumspect, and erring always on the side of providing too much information or context.

1 Like

Thanks you so much!!!
This worked "!npm install phantomjs-prebuilt". The first command suggestion "!npm install -g phantomjs-prebuilt" did not. I guess the -g was the problem there.

First of all, apologies for the patchy responses. Didn’t mean to have it that way. As you may have already noticed, I am not a full-time developer or an expert at either bokeh or notebooks. I am just a financial engineer trying to build something from scratch and learning on-the-go.

Appreciate your feedback on OSS maintainers and will keep that in mind for the future. In all honesty, having dealt with in-house or proprietory s/w most of my life, this is the first time I have used an open source forum to troubleshoot.

The only reason I was/am still pursuing this is because Bokeh is a great product and looks promising for something that we are doing at work. :slightly_smiling_face:

So, completely appreciate all the help here. An amazed by your dedication to help users.

2 Likes

Just for the logs and everyone else’s sake (if they ever want to troubleshoot), will document all that I tried. A list of things not to do and things I did wrong.
I initially installed using !pip install phantomjs used your suggestion to !npm install -g phantomjs-prebuilt as well. The second one did not work. Dont exactly remember the error. But it did not.
I think there was a suggestion in the beginning which said try running the command in the notebook.

Not knowing how exactly this works, I looked up where I can find the binaries for installed files in google colab. After lot of searching, I tried to associate the environment variable (BOKEH_PHANTOMJS_PATH) with different combinations of /usr/local/lib/python3.6/dist-packages/phantomjs +- (/) and run the export functions. Every time the error was same.

In the stack of error log I also noticed this

So I tried to change the permissions as well. The error remained the same.
Next, I tried this

The error is this NameError: name 'phantomjs' is not defined.

I also tried this:

Error was the same! I guess the phantomjs installation was the culprit.

1 Like

Hello Bryan/Good folks at Bokeh!

I think Google Colab finally upgraded to Bokeh 2.1.1. But now the export PNG that used to work with above code throws this error
Neither firefox and geckodriver nor a variant of chromium browser and chromedriver are available on system PATH. You can install the former with 'conda install -c conda-forge firefox geckodriver'.

I am simply using this command
x = export_png(plt, filename=Path + '/Print my Plot.png')

I have installed the following:
Selenium
Chromedriver

and also tried to set options as suggested by Bryan in one of the posts.

!pip install selenium
!apt-get update # to update ubuntu to correctly run apt install
!apt install chromium-chromedriver
!cp /usr/lib/chromium-browser/chromedriver /usr/bin
import sys
sys.path.insert(0,'/usr/lib/chromium-browser/chromedriver')
from selenium import webdriver
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
wd = webdriver.Chrome('chromedriver',chrome_options=chrome_options)
wd.get("https://www.webite-url.com")

If its as simple as pointing the system variable for Chromedriver to a specific location. Can you please let me know the variable name and where chromedriver can be found in Google Colab.

This seems to be happening on the binder tutorials as well. I have no idea why things should work locally but then fail to work on binder/collab, but here is an issue you can chime in on:

Thanks! Getting there now.