jupyterlab: bokeh plot displays in wrong browser - jupyter

I have a VM running jupyterlab and have opened it up for external access. When jupyter-lab starts, a local browser opens up, which is fine.
Externally, I access jupyterlab and things appear to work. However, when I plot, the output doesn't show up in the browser but instead appears as a new tab in the local browser which started up with jupyter-lab.
The same thing happens if I have %matplotlib inline.
The following is a little better in that now things display inline. However, a new tab still opens up in the other browser.
%matplotlib inline
from bokeh.plotting import figure, show, output_notebook
from bokeh.sampledata.iris import flowers
output_notebook()
colormap = {'setosa': 'red', 'versicolor': 'green', 'virginica': 'blue'}
colors = [colormap[x] for x in flowers['species']]
p = figure(title = "Iris Morphology")
p.xaxis.axis_label = 'Petal Length'
p.yaxis.axis_label = 'Petal Width'
p.circle(flowers["petal_length"], flowers["petal_width"],
color=colors, fill_alpha=0.2, size=10)
# output_file("iris.html", title="iris.py example")
show(p)

The problem is not related to my setup but instead simply to my lack of understanding regarding Bokeh. Bokeh has state. So, if you call output_file() or maybe even if not, it saves all your plots which causes them to also display in a new browser tab. The solution is to not do that :)
Putting the following code at the top of the example cell above fixed the issue:
bokeh.io.reset_output()
bokeh.io.output_notebook()
I found the answer here. Thank you bigreddot and martin-martin
Technically, mine is a duplicate question. However it was non-obvious enough that I'll leave it around.

Related

Error handling in Sublime Text Plugin API

I'm creating my first sublime plugin to be used internally and was wondering if there's a way to stop the plugin from executing and display an error message on screen like an alert?
I took a look at view#show_popup() but this didn't render for me. Below is how I attempted to show it:
if "WebContent" in subdirectories:
directory = ROOT_DIR + "/WebContent"
elif "Content" in subdirectories:
directory = ROOT_DIR + "/Content"
else:
self.view.show_popup('Directory not found', location=-1)
Working Principle:
The plugin takes some data from one view and then pastes them in another view. The plugin has two TextCommands. One command takes the data from the first view, opens a new view and then executes the 2nd command on the new view. The above snippet is in the 2nd command.
I was unable to find any resources to help with show_popup() or any other error handling.
Does any one have possible ideas?
view.show_popup() is for showing things like hover popups next to the cursor; it's used for things like the built in functionality for going to references/definitions for functions:
While you could in theory use this for error messages, it may not be the sort of user experience that anyone would expect.
Your code above is technically valid, but since the content is expected to be minihtml it may be hard to see because as just a single string all you're going to see is just the text (i.e. you have no font style, padding, etc):
Perhaps more importantly, when location is -1, the popup appears at the point in the buffer closest to the first cursor position, so depending on your circumstance it may be appearing in a place you don't expect, and then vanishing away before you can scroll to see it, etc.
What you want here is sublime.error_message(); given a string, it will display that string in a dialog for the user to interact with, and it also logs the error into the Sublime console as well so that there's an additional trace.

"ModuleNotFoundError: No module named 'PIL'

I have the same problem as was asked by trevor however the answers don't assist me at all.
I'm on Window 10, running Pyscriper 3.6.3.0 and Python 3.8.2 in 32 bit.
I've searched the Pillow site and those instruction just result in a different error where pip is invalid syntax. The biggest issue I'm finding is that there is way too much out of date on Google and the forums.
I was of the belief that Pillow already came with 3.8.2?
from tkinter import *
from PIL import ImageTk,Image
root = Tk()
root.title('TimeLord Frames')
root.iconbitmap('TBA') # Still need to work on icon.
frame = LabelFrame(root, text="This is my Frame.., padx=5, pady=5")
frame.pack(padx=10, pady=10)
b = Button(frame, text="Click Here")
b.pack()
root.mainloop()
I'm pretty sure I have found the problem. It comes from the line:
root.iconbitmap('TBA') # Still need to work on icon.
Because I haven't resolved an issue with the icon, it is looking at "from PIL import ImageTk,Image" and not connecting the 2 together. I have tried inserting the location of my icon, but it's not happy with that either. If I # out bothe line refering to images, I can get the program to run.
Cheers

MATLAB TODO: Fill in Description

I was trying to find something about LegendEntry in MATLAB, so I clicked it to open the help window, and this is what I saw:
If you want to see it yourself run this code:
h = plot(1:10,1:10);
legend('a')
h.Annotation.LegendInformation
Then you will see at the command window:
ans =
LegendEntry with properties:
IconDisplayStyle: 'on'
LegendEntry is a link to the help file for matlab.graphics.eventdata.LegendEntry which pops up the window in the picture above.
Are you familiar with this? Is this some kind of a problem with my installation?
I use MATLAB 2015a.
What's happened here is that a developer has left a TODO note to him or herself in the comments for matlab.graphics.eventdata.LegendEntry, and has forgotten to remove it before release.
If you'd noticed this in the most recent release, it would probably be worth bringing it to the notice of MathWorks with a bug report: but in fact I've just tried this on 16a and it looks like it's been removed already.
It's not a problem with your installation.

Autocomplete in wxpython if load from xrc

I am trying to work with xrc resource in wxpython.
It is good but where is one big "no" - there is no autocomplete of wxFrame class loadet from xrc. And other loaded from xrc classes too.
Is this right or I'am doing somthing wgong?
here is the part of code for example:
import wx
from wx import xrc
class MyApp(wx.App):
def OnInit(self):
if os.path.exists("phc.xrc"):
self.res = xrc.XmlResource("phc.xrc")
self.frame = self.res.LoadFrame(None, 'MyFrame')
self.list_box = xrc.XRCCTRL(self.frame, "list_box_1")
self.notebook = xrc.XRCCTRL(self.frame, "Notebook")
self.StatusBar= xrc.XRCCTRL(self.frame, "MFrame_statusbar")
self.list_ctrl= xrc.XRCCTRL(self.frame, "list_ctr_1")
Well, how good the autocomplete function is depends entirely on the editor/IDE that you are using. You didn't specify what you are using to write python scripts, but from personal experience I would say that it is probably true, that there is no autocomplete.
I've used Eclipse/PyDev, Spyder, SPE and PyCharm in the past and they all did not show an ability to autocomplete widgets created with XRC. You could still try to get the Emacs autocomplete for Python to work and try it there, but I doubt it'll work.
I did not find this a particular hindrance, but everyone's different, I guess. Hopefully, that answers your question.
Yes autocomplete wouldn't work here since our code doesn't know what the xrc is going to return. Your code gets to know about the type of variable (in this case, frame) only during runtime.
And, unfortunately/fortunately, we cannot assign 'type' to a variable in Python for the autocompletion to work.
But in Eclipse + PyDev plugin
you can add this statement for autocomplete to work:
assert isinstance(self.frame, wx.Frame)
autocomplete works after this statement.

programmatically add cells to an ipython notebook for report generation

I have seen a few of the talks by iPython developers about how to convert an ipython notebook to a blog post, a pdf, or even to an entire book(~min 43). The PDF-to-X converter interprets the iPython cells which are written in markdown or code and spits out a newly formatted document in one step.
My problem is that I would like to generate a large document where many of the figures and sections are programmatically generated - something like this. For this to work in iPython using the methods above, I would need to be able to write a function that would write other iPython-Code-Blocks. Does this capability exist?
#some pseudocode to give an idea
for variable in list:
image = make_image(variable)
write_iPython_Markdown_Cell(variable)
write_iPython_Image_cell(image)
I think this might be useful so I am wondering if:
generating iPython Cells through iPython is possible
if there is a reason that this is a bad idea and I should stick to a 'classic' solution like a templating library (Jinja).
thanks,
zach cp
EDIT:
As per Thomas' suggestion I posted on the ipython mailing list and got some feedback on the feasibility of this idea. In short - there are some technical difficulties that make this idea less than ideal for the original idea. For a repetitive report where you would like to generate markdown -cells and corresponding images/tables it is ore complicated to work through the ipython kernel/browser than to generate a report directly with a templating system like Jinja.
There's a Notebook gist by Fernando Perez here that demonstrates how to programmatically create new cells. Note that you can also pass metadata in, so if you're generating a report and want to turn the notebook into a slideshow, you can easily indicate whether the cell should be a slide, sub-slide, fragment, etc.
You can add any kind of cell, so what you want is straightforward now (though it probably wasn't when the question was asked!). E.g., something like this (untested code) should work:
from IPython.nbformat import current as nbf
nb = nbf.new_notebook()
cells = []
for var in my_list:
# Assume make_image() saves an image to file and returns the filename
image_file = make_image(var)
text = "Variable: %s\n![image](%s)" % (var, image_file)
cell = nbf.new_text_cell('markdown', text)
cells.append(cell)
nb['worksheets'].append(nbf.new_worksheet(cells=cells))
with open('my_notebook.ipynb', 'w') as f:
nbf.write(nb, f, 'ipynb')
I won't judge whether it's a good idea, but if you call get_ipython().set_next_input(s) in the notebook, it will create a new cell with the string s. This is what IPython uses internally for its %load and %recall commands.
Note that the accepted answer by Tal is a little deprecated and getting more deprecated: in ipython v3 you can (/should) import nbformat directly, and after that you need to specify which version of notebook you want to create.
So,
from IPython.nbformat import current as nbf
becomes
from nbformat import current as nbf
becomes
from nbformat import v4 as nbf
However, in this final version, the compatibility breaks because the write method is in the parent module nbformat, where all of the other methods used by Fernando Perez are in the v4 module, although some of them are under different names (e.g. new_text_cell('markdown', source) becomes new_markdown_cell(source)).
Here is an example of the v3 way of doing things: see generate_examples.py for the code and plotstyles.ipynb for the output. IPython 4 is, at time of writing, so new that using the web interface and clicking 'new notebook' still produces a v3 notebook.
Below is the code of the function which will load contents of a file and insert it into the next cell of the notebook:
from IPython.display import display_javascript
def make_cell(s):
text = s.replace('\n','\\n').replace("\"", "\\\"").replace("'", "\\'")
text2 = """var t_cell = IPython.notebook.get_selected_cell()
t_cell.set_text('{}');
var t_index = IPython.notebook.get_cells().indexOf(t_cell);
IPython.notebook.to_code(t_index);
IPython.notebook.get_cell(t_index).render();""".format(text)
display_javascript(text2, raw=True)
def insert_file(filename):
with open(filename, 'r') as content_file:
content = content_file.read()
make_cell(content)
See details in my blog.
Using the magics can be another solution. e.g.
get_ipython().run_cell_magic(u'HTML', u'', u'<font color=red>heffffo</font>')
Now that you can programatically generate HTML in a cell, you can format in any ways as you wish. Images are of course supported. If you want to repetitively generate output to multiple cells, just do multiple of the above with the string to be a placeholder.
p.s. I once had this need and reached this thread. I wanted to render a table (not the ascii output of lists and tuples) at that time. Later I found pandas.DataFrame is amazingly suited for my job. It generate HTML formatted tables automatically.
from IPython.display import display, Javascript
def add_cell(text, type='code', direct='above'):
text = text.replace('\n','\\n').replace("\"", "\\\"").replace("'", "\\'")
display(Javascript('''
var cell = IPython.notebook.insert_cell_{}("{}")
cell.set_text("{}")
'''.format(direct, type, text)));
for i in range(3):
add_cell(f'# heading{i}', 'markdown')
add_cell(f'code {i}')
codes above will add cells as follows:
#xingpei Pang solution is perfect, especially if you want to create customized code for each dataset having several groups for instance. However, the main issue with the javascript code is that if you run this code in a trusted notebook, it runs every time the notebook is loaded.
The solution I came up with is to clear the cell output after execution. The javascript code is stored in the output cell, so by clearing the output the code is gone and nothing is left to be executed in the trusted mode again. By using the code from here, the solution is the code below.
from IPython.display import display, Javascript, clear_output
def add_cell(text, type='code', direct='above'):
text = text.replace('\n','\\n').replace("\"", "\\\"").replace("'", "\\'")
display(Javascript('''
var cell = IPython.notebook.insert_cell_{}("{}")
cell.set_text("{}")
'''.format(direct, type, text)));
# create cells
for i in range(3):
add_cell(f'# heading{i}', 'markdown')
add_cell(f'code {i}')
# clean the javascript code from the current cell output
for i in range(10):
clear_output(wait=True)
Note that the clear_output() needs the be run several times to make sure the output is cleared.
As a slight update incorporating Tal's answer above, updates from Chris Barnes and a little digging in the nbformat docs, the following worked for me:
import nbformat
from nbformat import v4 as nbf
nb = nbf.new_notebook()
cells = [
nbf.new_code_cell(f"""print("Doing the thing: {i}")""")
for i in range(10)
]
nb.cells.extend(cells)
with open('generated_notebook.ipynb', 'w') as f:
nbformat.write(nb, f)
You can then start up the new artificial notebook and cut-n-paste cells where ever you need them.
This is unlikely to be the best way to do anything, but it's useful as a dirty hack. 🐱‍💻
This worked with the following versions:
Package Version
-------------------- ----------
ipykernel 5.3.0
ipython 7.15.0
jupyter 1.0.0
jupyter-client 6.1.3
jupyter-console 6.1.0
jupyter-core 4.6.3
nbconvert 5.6.1
nbformat 5.0.7
notebook 6.0.3
...
Using the command line goto the directory where the myfile.py file is located
and execute (Example):
C:\MyDir\pip install p2j
Then execute:
C:\MyDir\p2j myfile.py -t myfile.ipynb
Run in the Jupyter notebook:
!pip install p2j
Then, using the command line, go the corresponding directory where the file is located and execute:
python p2j <myfile.py> -t <myfile.ipynb>