I have a cell that looks like this:
from IPython.display import Image
i = Image(filename='test.png')
i
print("test")
The output is just:
test
I don't see the image in the output. I checked to see that the file exists (anyway, if it did not exist, you get an error).
Any clues?
creating the image with
i = Image(filename='test.png')
only creates the object to display. Objects are displayed by one of two actions:
a direct call to IPython.display.display(obj), e.g.
from IPython.display import display
display(i)
the displayhook, which automatically displays the result of the cell, which is to say putting i on the last line of the cell. The lone i in your example doesn't display because it is not the last thing in the cell. So while this doesn't display the image:
i = Image(filename='test.png')
i
print("test")
This would:
i = Image(filename='test.png')
print("test")
i
I had the same problem.
Matplot lib expects to show figs outside the command line, for example in the GTK or QT.
Use this: get_ipython().magic(u'matplotlib inline')
It will enable inline backend for usage with IPython notebook.
See more here and here.
After looking into the code, I can say, that under Windows, as of IPython 7.1.0, this is only supported with %matplotlib inline, which does not work under the interactive IPython shell.
There is extra code in Jupyter. The following example works with
jupyter qtconsole
jupyter notebook
jupyter console in principle, but only via external program, and then for the example the temporary file got deleted
def test_display():
import pyx
c = pyx.canvas.canvas()
circle = pyx.path.circle(0, 0, 2)
c.stroke(circle, [pyx.style.linewidth.Thick,pyx.color.rgb.red])
return c
display(test_display())
Related
I wish to have an interactive map that you can click where, once clicked, a SkewT and Hodograph will be plotted showing the information for that location. I have thus created a class where I add all the necessary informations using the metpy library and I am able to successfully create these graphs:
SkewT and Hodograph plotted
The problem comes when I'm trying to import the classes I've created to generate these plots into jupyterlab. Since the code to actually make these plots is quite cumbersome, I'd rather
keep the code in a separate file and import my SoundingGraphs class, but it's not working. The graphs never get plotted inside a cell, they instead appear in the logs as a Warning and as an Info and I have no idea why:
Graphs appearing inside logs
Tried to use plt.show() inside my file, tried returning plt to then use plt.show() inside a cell of the notebook, tried using %matplotlib widget, %matplotlib notebook and %matplotlib inline, tried changing jupyterlab versions, none of these changed anything.
I have found one solution that I disliked, but that does work, which is rather than doing a plt.show(), to instead do this inside my class:
buffer = BytesIO()
plt.savefig(buffer, format='png')
return buffer
And in the notebook I would do:
image = Image()
display(image)
def on_generate_button_clicked(b):
buffer = SoundingGraphs(infos)
buffer.seek(0)
image.value=buffer.read()
image.format='png'
generate_button.on_click(on_generate_button_clicked)
I don't quite like this approach because further down the line I would like to add interactivity to my plots, like show values of plot when hovered and things like that, thus I don't just want to show an image. So I'd like to know if it is indeed possible to plt.show() a plot created inside another file in a cell.
Using:
Python 3.6.9
jupyterlab==3.2.9
jupyterlab-pygments==0.1.2
jupyterlab-server==2.10.3
jupyterlab-widgets==1.1.0
ipykernel==5.5.6
ipyleaflet==0.14.0
ipympl==0.8.8
ipython==7.16.3
ipython-genutils==0.2.0
ipywidgets==7.7.0
matplotlib==3.3.4
Thanks!
Yes, it is possible after all!
%matplotlib widget needs to be used at the start of the notebook and since the class method will be called from another function (on a button.on_click event), it is possible to use the #out.capture() decorator above it so that the plt.show() gets displayed. It's also possible to make the figure a class attribute to be able to have more control.
So here's a bit of working code if someone would like to replicate:
Notebook
%matplotlib widget
from ipywidgets import Button, Output
from myfile import MyClass
out = Output()
example_button = Button(
description='Example',
disabled=False,
button_style='',
tooltip='Click me'
)
#out.capture()
def on_example_button_clicked(b):
example_button.disabled = True
myclass = MyClass()
myclass.create_plot()
out.clear_output(wait=True)
display(myclass.fig.canvas)
example_button.disabled = False
example_button.on_click(on_example_button_clicked)
display(example_button)
display(out)
myfile.py
import matplotlib.pyplot as plt
class MyClass():
def __init__(self):
plt.ioff() # otherwise it'll also show inside logs
plt.clf()
self.fig = plt.figure()
def create_plot(self):
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
I would like to know if there is a way to update a panel pane content through a python callback.
If I define a Parameterized custom class the following way:
import panel as pn
pn.extension()
import param
class Myclass(param.Parameterized):
letter = param.ObjectSelector(
objects=['a', 'b', 'c', 'd'],
default='b',
)
#param.depends('letter')
def text(self):
return(pn.pane.Str(self.letter))
instance = Myclass()
If I output this instance in my notebook, I get the following:
pn.Row(instance.param.letter, instance.text)
yields:
However, when I select another entry in the dropdown list, the text on the right is not updated:
I know that the parameter has been updated, and that the text callback is fired (through debugging). Yet, no update is done in my notebook.
I feel that this example is very similar to the Sine wave example in the documentation (https://panel.holoviz.org/user_guide/Param.html), but I don't get what I am doing wrong...
Ideally, the answer should also work with a panel.pane.HTML as well as a panel.pane.Str.
I tried your code in jupyter notebook and it works: the text gets updated when the dropdown changes.
If I try it in my jupyter lab it doesn't work, but I have that more often. I think with me it's a jupyter version / installation thing.
So I think your code is correct. You could try updating your jupyter notebook or your panel or param packages.
I am writting a jupyter notebook in which at the begining I am creating a complex tab ipywidget for the user to select some inptus (see picture). I am wondering if there is any way to hide to the user the code cell that contains the code to create that widget.
I saw on this forum some questiosn about hiding code when exporting the notebook but in my case the user will access the j_notebook online. Just would like to avoid complexity by hiding some code cells
in module.py
import ipywidgets as ipyw
from IPython.display import display
button = ipyw.Button('Try this:')
out = ipyw.Output()
def print_it(button):
with out:
print('You clicked it')
button.on_click(print_it)
display(ipyw.VBox(children=[button, out]))
In your notebook:
import module
Good morning SO,
Setup :
Windows 7 (I know)
Sublime Text 3
Python 3.6
My problem :
I have some 28x28 images in a file, say one of them is at the relative path 'MyDir/myimage.png'
I'm trying to display the example image using the display module in the package IPython
from IPython.display import display,Image
img=Image(filename='MyDir/myimage.png')
display(img)
The problem is that instead of outputing the image in a figure, it only outputs the type of the object img in the console (display displays only in console).
Output :
<IPython.core.display.Image object>
Any ideas?
IPython (interactive python) won't work as expected in the console.
But in jupyter notebook, for instance, all goes well:
There's also qtconsole which sounds like it's just a more console-like jupyter notebook. I haven't checked it out, since between vscode and jupyter notebook, I've been fine thus far.
To learn more, you could search for comparisons between tools like jupyter and qt. And also take a look at the IPython docs. But if you just want the darn thing to show you an image, you could run your python script in jupyter or the like. Or use PIL as this answer to another question mentions.
Also, you could use matplotlib.pyplot to show images instead (this works in console and in jupyter):
from matplotlib.pyplot import figure, imshow, axis, show
from matplotlib.image import imread
import numpy as np
import os
imageDirectory = "c:\\some\\directory\\of\\images"
list_of_files = np.array(os.listdir(imageDirectory))[0:20] # just show the first 20 images
fig = figure()
number_of_files = len(list_of_files)
for i in range(number_of_files):
a=fig.add_subplot(1,number_of_files,i+1)
image = imread(os.path.join(imageDirectory, list_of_files[i]))
imshow(image,cmap='Greys_r')
axis('off')
show()
In IPython notebook, the following code displays the SVG below the cell:
from IPython.display import SVG
SVG(url='http://upload.wikimedia.org/wikipedia/en/a/a4/Flag_of_the_United_States.svg')
The following displays nothing:
from IPython.display import SVG
def show_svg():
SVG(url='http://upload.wikimedia.org/wikipedia/en/a/a4/Flag_of_the_United_States.svg')
Is there a way to display an SVG from within a function (or a class)?
You need to display the SVG like
from IPython.display import SVG, display
def show_svg():
display(SVG(url='http://upload.wikimedia.org/wikipedia/en/a/a4/Flag_of_the_United_States.svg'))
You first example works as the SVG object returns itself an is subsequently displayed by the IPython display machinery. As you want to create your SVG object in a custom method, you need to take care of the displaying.
The display call is similar to the ordinary print statement, but can handle different representations like images, html, latex, etc. For details have a look at the rich display documentation.
Add return to your function :
from IPython.display import SVG
def show_svg():
return SVG(url='http://upload.wikimedia.org/wikipedia/en/a/a4/Flag_of_the_United_States.svg')
Then call your functions as the last line in cell:
show_svg()