This is to test various displays in the Jupyter Notebook (classic) or JupyterLab: LaTeX, interactive widgets, 2d and 3d plots, animated 3d plots, Matplotlib interface, etc., especially in the scope of %display latex
.
version()
'SageMath version 10.2.rc1, Release Date: 2023-11-10'
%display latex
sin(x^2)
Check that long outputs are wrapped (cf. this comment in #36129):
((1+x)^20).expand()
%display latex
¶type(x)
set([1,2])
RubiksCube()
IntegerModRing(6)
_repr_latex_
¶IPython implements LaTeX display of all objects that are endowed with a method _repr_latex_
, cf. IPyhton's rich display documentation.
%display plain
s = sin(x^2)
s
sin(x^2)
In the plain text mode, the only way to get the LaTeX display of some object is via the function view
, which generates a pdf file:
view(s)
Let us test the _repr_latex_
mechanism of IPython via the method _latex_
of Sage objects:
s._latex_()
'\\sin\\left(x^{2}\\right)'
class NativeDisplay(SageObject):
def __init__(self, data):
self._data = data
def _repr_latex_(self):
try:
return '$' + self._data._latex_() + '$'
except (AttributeError, NotImplementedError):
return None # if None is returned, plain text is used
We get a LaTeX display, even if we are the scope of %display plain
:
s
sin(x^2)
NativeDisplay(s)
NativeDisplay([s, s])
<__main__.NativeDisplay object at 0x7f749fe78370>
g = plot(s)
print(NativeDisplay(g))
<__main__.NativeDisplay object at 0x7f749fe796f0>
Test of IPython native LaTeX display in the scope of %display latex
(this fails in Sage 9.6.rc2 and Sage 10.2.rc1):
%display latex
NativeDisplay(s)
%display latex
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
plt.show()
%display plain
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
plt.show()
%matplotlib notebook
provides an interactive Matplotlib window in the Jupyter Notebook. It is however not supported by Jupyterlab; one should use %matplotlib widget
instead (which requires the Python package ipympl
).
This failed in Sage 9.6.beta5 but has been fixed in Sage 9.6.beta7:
%display latex
#%matplotlib notebook
%matplotlib widget
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
plt.show()
Test of the solution proposed at #33469:
sage.repl.display.formatter.IPYTHON_NATIVE_TYPES
import ipywidgets
sage.repl.display.formatter.IPYTHON_NATIVE_TYPES += (ipywidgets.Widget,)
sage.repl.display.formatter.IPYTHON_NATIVE_TYPES
%matplotlib widget
import matplotlib.pyplot as plt
plt.plot([1, 2, 3, 4])
plt.ylabel('some numbers')
plt.show()
%display latex
¶First we test it with %display plain
:
%display plain
@interact
def f(n=10):
print(n)
Interactive function <function f at 0x7f74ef5c85e0> with 1 widget n: IntSlider(value=10, description='n', max=30, min=-10)
and then we switch on the LaTeX display:
%display latex
@interact
def f(n=10):
print(n)
Interactive function <function f at 0x7f74ef5c8ca0> with 1 widget n: IntSlider(value=10, description='n', max=30, min=-10)
%display latex
@interact
def _(a = slider([1..10]),
color=Color('red'),
axes=checkbox(True, 'Show axes'),
x_label=input_box('$x$', 'x-label', str),
y_label=input_box('$y$', 'y-label', str)):
axes_labels = [x_label, y_label] if axes else None
show(plot(cos(a*x), (x, 0, 2*pi), color=color, thickness=2),
axes=axes, axes_labels=axes_labels)
Interactive function <function _ at 0x7f74a002fe20> with 5 widgets a: SelectionSlider(description='a', options=(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), value=1) color: SageColorPicker(value='#ff0000', description='color') axes: Checkbox(value=True, description='Show axes') x_label: TransformText(value='$x$', description='x-label', layout=Layout(max_width='81em')) y_label: TransformText(value='$y$', description='y-label', layout=Layout(max_width='81em'))
x, y = var('x y')
g = (plot3d(sin(x*y), (x, -pi, pi), (y, -pi, pi), color='green')
+ sphere()
+ icosahedron(center=(0, 0, 2), color='red')
+ text3d('A nice plot', (-4, -4, 2), color='orange',
fontsize='200%', fontfamily='serif', fontweight='bold'))
g
n = 20
animate([plot3d(sin((x - k*pi/(n-1))*y), (x, -pi, pi), (y, -pi, pi))
for k in range(n)]).interactive(delay=10)