Code Cells¶
Code, Output, Streams¶
An empty code cell:
[ ]:
Two empty lines:
[ ]:
Leading/trailing empty lines:
[1]:
# 2 empty lines before, 1 after
A simple output:
[2]:
6 * 7
[2]:
42
The standard output stream:
[3]:
print('Hello, world!')
Hello, world!
Normal output + standard output
[4]:
print('Hello, world!')
6 * 7
Hello, world!
[4]:
42
The standard error stream is highlighted and displayed just below the code cell. The standard output stream comes afterwards (with no special highlighting). Finally, the “normal” output is displayed.
[5]:
import sys
print("I'll appear on the standard error stream", file=sys.stderr)
print("I'll appear on the standard output stream")
"I'm the 'normal' output"
I'll appear on the standard output stream
I'll appear on the standard error stream
[5]:
"I'm the 'normal' output"
Note
Using the IPython kernel, the order is actually mixed up, see https://github.com/ipython/ipykernel/issues/280.
Special Display Formats¶
Local Image Files¶
[6]:
from IPython.display import Image
i = Image(filename='images/notebook_icon.png')
i
[6]:
[7]:
display(i)
See also SVG support for LaTeX.
[8]:
from IPython.display import SVG
SVG(filename='images/python_logo.svg')
[8]:
Image URLs¶
[9]:
Image(url='https://www.python.org/static/img/python-logo-large.png')
[9]:

[10]:
Image(url='https://www.python.org/static/img/python-logo-large.png', embed=True)
[10]:
[11]:
Image(url='https://jupyter.org/assets/homepage/main-logo.svg')
[11]:
Math¶
[12]:
from IPython.display import Math
eq = Math(r'\int\limits_{-\infty}^\infty f(x) \delta(x - x_0) dx = f(x_0)')
eq
[12]:
[13]:
display(eq)
[14]:
from IPython.display import Latex
Latex(r'This is a \LaTeX{} equation: $a^2 + b^2 = c^2$')
[14]:
[15]:
%%latex
\begin{equation}
\int\limits_{-\infty}^\infty f(x) \delta(x - x_0) dx = f(x_0)
\end{equation}
Plots¶
Make sure to use at least version 0.1.6 of the matplotlib-inline package (which is an automatic dependency of the ipython package).
By default, the plots created with the “inline” backend have the wrong size. More specifically, PNG plots (the default) will be slightly larger than SVG and PDF plots.
This can be fixed easily by creating a file named matplotlibrc (in the directory where your Jupyter notebooks live, e.g. in this directory: matplotlibrc) and adding the following line:
figure.dpi: 96
If you are using Git to manage your files, don’t forget to commit this local configuration file to your repository. Different directories can have different local configurations. If a given configuration should apply to multiple directories, symbolic links can be created in each directory.
For more details, see Default Values for Matplotlib’s “inline” Backend.
By default, plots are generated in the PNG format. In most cases, it looks better if SVG plots are used for HTML output and PDF plots are used for LaTeX/PDF. This can be achieved by setting nbsphinx_execute_arguments in your conf.py file like this:
nbsphinx_execute_arguments = [
"--InlineBackend.figure_formats={'svg', 'pdf'}",
]
In the following example, nbsphinx should use an SVG image in the HTML output and a PDF image for LaTeX/PDF output (other Jupyter clients like JupyterLab will still show the default PNG format).
[16]:
import matplotlib.pyplot as plt
[17]:
fig, ax = plt.subplots(figsize=[6, 3])
ax.plot([4, 9, 7, 20, 6, 33, 13, 23, 16, 62, 8]);
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[17], line 1
----> 1 fig, ax = plt.subplots(figsize=[6, 3])
2 ax.plot([4, 9, 7, 20, 6, 33, 13, 23, 16, 62, 8]);
File /usr/lib/python3/dist-packages/matplotlib/pyplot.py:1450, in subplots(nrows, ncols, sharex, sharey, squeeze, width_ratios, height_ratios, subplot_kw, gridspec_kw, **fig_kw)
1304 def subplots(nrows=1, ncols=1, *, sharex=False, sharey=False, squeeze=True,
1305 width_ratios=None, height_ratios=None,
1306 subplot_kw=None, gridspec_kw=None, **fig_kw):
1307 """
1308 Create a figure and a set of subplots.
1309
(...)
1448
1449 """
-> 1450 fig = figure(**fig_kw)
1451 axs = fig.subplots(nrows=nrows, ncols=ncols, sharex=sharex, sharey=sharey,
1452 squeeze=squeeze, subplot_kw=subplot_kw,
1453 gridspec_kw=gridspec_kw, height_ratios=height_ratios,
1454 width_ratios=width_ratios)
1455 return fig, axs
File /usr/lib/python3/dist-packages/matplotlib/_api/deprecation.py:454, in make_keyword_only.<locals>.wrapper(*args, **kwargs)
448 if len(args) > name_idx:
449 warn_deprecated(
450 since, message="Passing the %(name)s %(obj_type)s "
451 "positionally is deprecated since Matplotlib %(since)s; the "
452 "parameter will become keyword-only %(removal)s.",
453 name=name, obj_type=f"parameter of {func.__name__}()")
--> 454 return func(*args, **kwargs)
File /usr/lib/python3/dist-packages/matplotlib/pyplot.py:783, in figure(num, figsize, dpi, facecolor, edgecolor, frameon, FigureClass, clear, **kwargs)
773 if len(allnums) == max_open_warning >= 1:
774 _api.warn_external(
775 f"More than {max_open_warning} figures have been opened. "
776 f"Figures created through the pyplot interface "
(...)
780 f"Consider using `matplotlib.pyplot.close()`.",
781 RuntimeWarning)
--> 783 manager = new_figure_manager(
784 num, figsize=figsize, dpi=dpi,
785 facecolor=facecolor, edgecolor=edgecolor, frameon=frameon,
786 FigureClass=FigureClass, **kwargs)
787 fig = manager.canvas.figure
788 if fig_label:
File /usr/lib/python3/dist-packages/matplotlib/pyplot.py:358, in new_figure_manager(*args, **kwargs)
356 def new_figure_manager(*args, **kwargs):
357 """Create a new figure manager instance."""
--> 358 _warn_if_gui_out_of_main_thread()
359 return _get_backend_mod().new_figure_manager(*args, **kwargs)
File /usr/lib/python3/dist-packages/matplotlib/pyplot.py:336, in _warn_if_gui_out_of_main_thread()
334 def _warn_if_gui_out_of_main_thread():
335 warn = False
--> 336 if _get_required_interactive_framework(_get_backend_mod()):
337 if hasattr(threading, 'get_native_id'):
338 # This compares native thread ids because even if Python-level
339 # Thread objects match, the underlying OS thread (which is what
340 # really matters) may be different on Python implementations with
341 # green threads.
342 if threading.get_native_id() != threading.main_thread().native_id:
File /usr/lib/python3/dist-packages/matplotlib/pyplot.py:207, in _get_backend_mod()
198 """
199 Ensure that a backend is selected and return it.
200
201 This is currently private, but may be made public in the future.
202 """
203 if _backend_mod is None:
204 # Use __getitem__ here to avoid going through the fallback logic (which
205 # will (re)import pyplot and then call switch_backend if we need to
206 # resolve the auto sentinel)
--> 207 switch_backend(dict.__getitem__(rcParams, "backend"))
208 return _backend_mod
File /usr/lib/python3/dist-packages/matplotlib/pyplot.py:265, in switch_backend(newbackend)
262 rcParamsOrig["backend"] = "agg"
263 return
--> 265 backend_mod = importlib.import_module(
266 cbook._backend_module_name(newbackend))
268 required_framework = _get_required_interactive_framework(backend_mod)
269 if required_framework is not None:
File /usr/lib/python3.12/importlib/__init__.py:90, in import_module(name, package)
88 break
89 level += 1
---> 90 return _bootstrap._gcd_import(name[level:], package, level)
File <frozen importlib._bootstrap>:1387, in _gcd_import(name, package, level)
File <frozen importlib._bootstrap>:1360, in _find_and_load(name, import_)
File <frozen importlib._bootstrap>:1310, in _find_and_load_unlocked(name, import_)
File <frozen importlib._bootstrap>:488, in _call_with_frames_removed(f, *args, **kwds)
File <frozen importlib._bootstrap>:1387, in _gcd_import(name, package, level)
File <frozen importlib._bootstrap>:1360, in _find_and_load(name, import_)
File <frozen importlib._bootstrap>:1331, in _find_and_load_unlocked(name, import_)
File <frozen importlib._bootstrap>:935, in _load_unlocked(spec)
File <frozen importlib._bootstrap_external>:995, in exec_module(self, module)
File <frozen importlib._bootstrap>:488, in _call_with_frames_removed(f, *args, **kwds)
File /usr/lib/python3/dist-packages/matplotlib_inline/__init__.py:1
----> 1 from . import backend_inline, config # noqa
3 __version__ = "0.2.1"
5 # we can't ''.join(...) otherwise finding the version number at build time requires
6 # import which introduces IPython and matplotlib at build time, and thus circular
7 # dependencies.
File /usr/lib/python3/dist-packages/matplotlib_inline/backend_inline.py:236
231 ip.events.unregister("post_run_cell", configure_once)
233 ip.events.register("post_run_cell", configure_once)
--> 236 _enable_matplotlib_integration()
239 def _fetch_figure_metadata(fig):
240 """Get some metadata to help with displaying a figure."""
File /usr/lib/python3/dist-packages/matplotlib_inline/backend_inline.py:218, in _enable_matplotlib_integration()
216 backend = matplotlib.get_backend(auto_select=False)
217 else:
--> 218 backend = matplotlib.rcParams._get("backend")
220 if ip and backend in ("inline", "module://matplotlib_inline.backend_inline"):
221 from IPython.core.pylabtools import activate_matplotlib
AttributeError: 'RcParams' object has no attribute '_get'
For comparison, this is how it would look in PNG format …
[18]:
%config InlineBackend.figure_formats = ['png']
[19]:
fig
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[19], line 1
----> 1 fig
NameError: name 'fig' is not defined
… and in 'png2x' (a.k.a. 'retina') format:
[20]:
%config InlineBackend.figure_formats = ['png2x']
[21]:
fig
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[21], line 1
----> 1 fig
NameError: name 'fig' is not defined
Instead of the default inline plotting backend, you can also use the widget backend (which needs the ipympl package to be installed):
[22]:
%matplotlib widget
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[22], line 1
----> 1 get_ipython().run_line_magic('matplotlib', 'widget')
File /usr/lib/python3/dist-packages/IPython/core/interactiveshell.py:2456, in InteractiveShell.run_line_magic(self, magic_name, line, _stack_depth)
2454 kwargs['local_ns'] = self.get_local_scope(stack_depth)
2455 with self.builtin_trap:
-> 2456 result = fn(*args, **kwargs)
2458 # The code below prevents the output from being displayed
2459 # when using magics with decorator @output_can_be_silenced
2460 # when the last Python token in the expression is a ';'.
2461 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
File /usr/lib/python3/dist-packages/IPython/core/magics/pylab.py:99, in PylabMagics.matplotlib(self, line)
97 print("Available matplotlib backends: %s" % backends_list)
98 else:
---> 99 gui, backend = self.shell.enable_matplotlib(args.gui.lower() if isinstance(args.gui, str) else args.gui)
100 self._show_matplotlib_backend(args.gui, backend)
File /usr/lib/python3/dist-packages/IPython/core/interactiveshell.py:3633, in InteractiveShell.enable_matplotlib(self, gui)
3612 def enable_matplotlib(self, gui=None):
3613 """Enable interactive matplotlib and inline figure support.
3614
3615 This takes the following steps:
(...)
3631 display figures inline.
3632 """
-> 3633 from matplotlib_inline.backend_inline import configure_inline_support
3635 from IPython.core import pylabtools as pt
3636 gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select)
File /usr/lib/python3/dist-packages/matplotlib_inline/__init__.py:1
----> 1 from . import backend_inline, config # noqa
3 __version__ = "0.2.1"
5 # we can't ''.join(...) otherwise finding the version number at build time requires
6 # import which introduces IPython and matplotlib at build time, and thus circular
7 # dependencies.
File /usr/lib/python3/dist-packages/matplotlib_inline/backend_inline.py:236
231 ip.events.unregister("post_run_cell", configure_once)
233 ip.events.register("post_run_cell", configure_once)
--> 236 _enable_matplotlib_integration()
239 def _fetch_figure_metadata(fig):
240 """Get some metadata to help with displaying a figure."""
File /usr/lib/python3/dist-packages/matplotlib_inline/backend_inline.py:218, in _enable_matplotlib_integration()
216 backend = matplotlib.get_backend(auto_select=False)
217 else:
--> 218 backend = matplotlib.rcParams._get("backend")
220 if ip and backend in ("inline", "module://matplotlib_inline.backend_inline"):
221 from IPython.core.pylabtools import activate_matplotlib
AttributeError: 'RcParams' object has no attribute '_get'
[23]:
fig, ax = plt.subplots(figsize=[6, 3])
ax.plot([4, 9, 7, 20, 6, 33, 13, 23, 16, 62, 8]);
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[23], line 1
----> 1 fig, ax = plt.subplots(figsize=[6, 3])
2 ax.plot([4, 9, 7, 20, 6, 33, 13, 23, 16, 62, 8]);
File /usr/lib/python3/dist-packages/matplotlib/pyplot.py:1450, in subplots(nrows, ncols, sharex, sharey, squeeze, width_ratios, height_ratios, subplot_kw, gridspec_kw, **fig_kw)
1304 def subplots(nrows=1, ncols=1, *, sharex=False, sharey=False, squeeze=True,
1305 width_ratios=None, height_ratios=None,
1306 subplot_kw=None, gridspec_kw=None, **fig_kw):
1307 """
1308 Create a figure and a set of subplots.
1309
(...)
1448
1449 """
-> 1450 fig = figure(**fig_kw)
1451 axs = fig.subplots(nrows=nrows, ncols=ncols, sharex=sharex, sharey=sharey,
1452 squeeze=squeeze, subplot_kw=subplot_kw,
1453 gridspec_kw=gridspec_kw, height_ratios=height_ratios,
1454 width_ratios=width_ratios)
1455 return fig, axs
File /usr/lib/python3/dist-packages/matplotlib/_api/deprecation.py:454, in make_keyword_only.<locals>.wrapper(*args, **kwargs)
448 if len(args) > name_idx:
449 warn_deprecated(
450 since, message="Passing the %(name)s %(obj_type)s "
451 "positionally is deprecated since Matplotlib %(since)s; the "
452 "parameter will become keyword-only %(removal)s.",
453 name=name, obj_type=f"parameter of {func.__name__}()")
--> 454 return func(*args, **kwargs)
File /usr/lib/python3/dist-packages/matplotlib/pyplot.py:783, in figure(num, figsize, dpi, facecolor, edgecolor, frameon, FigureClass, clear, **kwargs)
773 if len(allnums) == max_open_warning >= 1:
774 _api.warn_external(
775 f"More than {max_open_warning} figures have been opened. "
776 f"Figures created through the pyplot interface "
(...)
780 f"Consider using `matplotlib.pyplot.close()`.",
781 RuntimeWarning)
--> 783 manager = new_figure_manager(
784 num, figsize=figsize, dpi=dpi,
785 facecolor=facecolor, edgecolor=edgecolor, frameon=frameon,
786 FigureClass=FigureClass, **kwargs)
787 fig = manager.canvas.figure
788 if fig_label:
File /usr/lib/python3/dist-packages/matplotlib/pyplot.py:358, in new_figure_manager(*args, **kwargs)
356 def new_figure_manager(*args, **kwargs):
357 """Create a new figure manager instance."""
--> 358 _warn_if_gui_out_of_main_thread()
359 return _get_backend_mod().new_figure_manager(*args, **kwargs)
File /usr/lib/python3/dist-packages/matplotlib/pyplot.py:336, in _warn_if_gui_out_of_main_thread()
334 def _warn_if_gui_out_of_main_thread():
335 warn = False
--> 336 if _get_required_interactive_framework(_get_backend_mod()):
337 if hasattr(threading, 'get_native_id'):
338 # This compares native thread ids because even if Python-level
339 # Thread objects match, the underlying OS thread (which is what
340 # really matters) may be different on Python implementations with
341 # green threads.
342 if threading.get_native_id() != threading.main_thread().native_id:
File /usr/lib/python3/dist-packages/matplotlib/pyplot.py:207, in _get_backend_mod()
198 """
199 Ensure that a backend is selected and return it.
200
201 This is currently private, but may be made public in the future.
202 """
203 if _backend_mod is None:
204 # Use __getitem__ here to avoid going through the fallback logic (which
205 # will (re)import pyplot and then call switch_backend if we need to
206 # resolve the auto sentinel)
--> 207 switch_backend(dict.__getitem__(rcParams, "backend"))
208 return _backend_mod
File /usr/lib/python3/dist-packages/matplotlib/pyplot.py:265, in switch_backend(newbackend)
262 rcParamsOrig["backend"] = "agg"
263 return
--> 265 backend_mod = importlib.import_module(
266 cbook._backend_module_name(newbackend))
268 required_framework = _get_required_interactive_framework(backend_mod)
269 if required_framework is not None:
File /usr/lib/python3.12/importlib/__init__.py:90, in import_module(name, package)
88 break
89 level += 1
---> 90 return _bootstrap._gcd_import(name[level:], package, level)
File <frozen importlib._bootstrap>:1387, in _gcd_import(name, package, level)
File <frozen importlib._bootstrap>:1360, in _find_and_load(name, import_)
File <frozen importlib._bootstrap>:1310, in _find_and_load_unlocked(name, import_)
File <frozen importlib._bootstrap>:488, in _call_with_frames_removed(f, *args, **kwds)
File <frozen importlib._bootstrap>:1387, in _gcd_import(name, package, level)
File <frozen importlib._bootstrap>:1360, in _find_and_load(name, import_)
File <frozen importlib._bootstrap>:1331, in _find_and_load_unlocked(name, import_)
File <frozen importlib._bootstrap>:935, in _load_unlocked(spec)
File <frozen importlib._bootstrap_external>:995, in exec_module(self, module)
File <frozen importlib._bootstrap>:488, in _call_with_frames_removed(f, *args, **kwds)
File /usr/lib/python3/dist-packages/matplotlib_inline/__init__.py:1
----> 1 from . import backend_inline, config # noqa
3 __version__ = "0.2.1"
5 # we can't ''.join(...) otherwise finding the version number at build time requires
6 # import which introduces IPython and matplotlib at build time, and thus circular
7 # dependencies.
File /usr/lib/python3/dist-packages/matplotlib_inline/backend_inline.py:236
231 ip.events.unregister("post_run_cell", configure_once)
233 ip.events.register("post_run_cell", configure_once)
--> 236 _enable_matplotlib_integration()
239 def _fetch_figure_metadata(fig):
240 """Get some metadata to help with displaying a figure."""
File /usr/lib/python3/dist-packages/matplotlib_inline/backend_inline.py:218, in _enable_matplotlib_integration()
216 backend = matplotlib.get_backend(auto_select=False)
217 else:
--> 218 backend = matplotlib.rcParams._get("backend")
220 if ip and backend in ("inline", "module://matplotlib_inline.backend_inline"):
221 from IPython.core.pylabtools import activate_matplotlib
AttributeError: 'RcParams' object has no attribute '_get'
Pandas Dataframes¶
Pandas dataframes should be displayed as nicely formatted HTML tables (if you are using HTML output).
[24]:
import numpy as np
import pandas as pd
[25]:
np.random.seed(0)
df = pd.DataFrame(np.random.randint(0, 100, size=[10, 4]),
columns=[r'$\alpha$', r'$\beta$', r'$\gamma$', r'$\delta$'])
df
[25]:
| $\alpha$ | $\beta$ | $\gamma$ | $\delta$ | |
|---|---|---|---|---|
| 0 | 44 | 47 | 64 | 67 |
| 1 | 67 | 9 | 83 | 21 |
| 2 | 36 | 87 | 70 | 88 |
| 3 | 88 | 12 | 58 | 65 |
| 4 | 39 | 87 | 46 | 88 |
| 5 | 81 | 37 | 25 | 77 |
| 6 | 72 | 9 | 20 | 80 |
| 7 | 69 | 79 | 47 | 64 |
| 8 | 82 | 99 | 88 | 49 |
| 9 | 29 | 19 | 19 | 14 |
Markdown Content¶
[26]:
from IPython.display import Markdown
[27]:
md = Markdown("""
# Markdown
It *should* show up as **formatted** text
with things like [links] and images.
[links]: https://jupyter.org/

## Markdown Extensions
There might also be mathematical equations like
$a^2 + b^2 = c^2$
and even tables:
A | B | A and B
------|-------|--------
False | False | False
True | False | False
False | True | False
True | True | True
""")
md
YouTube Videos¶
[28]:
from IPython.display import YouTubeVideo
YouTubeVideo('9_OIs49m56E')
[28]:
Interactive Widgets (HTML only)¶
The basic widget infrastructure is provided by the ipywidgets module. More advanced widgets are available in separate packages, see for example https://jupyter.org/widgets.
The JavaScript code which is needed to display Jupyter widgets is loaded automatically (using RequireJS). If you want to use non-default URLs or local files, you can use the nbsphinx_widgets_path and nbsphinx_requirejs_path settings.
Other Languages
The examples shown here are using Python, but the widget technology can also be used with different Jupyter kernels (i.e. with different programming languages).
Troubleshooting¶
To obtain more information if widgets are not displayed as expected, you will need to look at the error message in the web browser console.
To figure out how to open the web browser console, you may look at the web browser documentation:
The error is most probably linked to the JavaScript files not being loaded or loaded in the wrong order within the HTML file. To analyze the error, you can inspect the HTML file within the web browser (e.g.: right-click on the page and select View Page Source) and look at the <head> section of the page. That section should contain some JavaScript libraries. Those relevant for widgets are:
<!-- require.js is a mandatory dependency for jupyter-widgets -->
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<!-- jupyter-widgets JavaScript -->
<script type="text/javascript" src="https://unpkg.com/@jupyter-widgets/html-manager@^0.18.0/dist/embed-amd.js"></script>
<!-- JavaScript containing custom Jupyter widgets -->
<script src="../_static/embed-widgets.js"></script>
The two first elements are mandatory. The third one is required only if you designed your own widgets but did not publish them on npm.js.
If those libraries appear in a different order, the widgets won’t be displayed.
Here is a list of possible solutions:
Arbitrary JavaScript Output (HTML only)¶
[29]:
%%javascript
var text = document.createTextNode("Hello, I was generated with JavaScript!");
// Content appended to "element" will be visible in the output area:
element.appendChild(text);
Unsupported Output Types¶
If a code cell produces data with an unsupported MIME type, the Jupyter Notebook doesn’t generate any output. nbsphinx, however, shows a warning message.
[30]:
display({
'text/x-python': 'print("Hello, world!")',
'text/x-haskell': 'main = putStrLn "Hello, world!"',
}, raw=True)
Data type cannot be displayed: text/x-python, text/x-haskell
ANSI Colors¶
The standard output and standard error streams may contain ANSI escape sequences to change the text and background colors.
[31]:
print('BEWARE: \x1b[1;33;41mugly colors\x1b[m!', file=sys.stderr)
print('AB\x1b[43mCD\x1b[35mEF\x1b[1mGH\x1b[4mIJ\x1b[7m'
'KL\x1b[49mMN\x1b[39mOP\x1b[22mQR\x1b[24mST\x1b[27mUV')
ABCDEFGHIJKLMNOPQRSTUV
BEWARE: ugly colors!
The following code showing the 8 basic ANSI colors is based on https://web.archive.org/web/20231225185739/https://tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html. Each of the 8 colors has an “intense” variation, which is used for bold text.
[32]:
text = ' XYZ '
formatstring = '\x1b[{}m' + text + '\x1b[m'
print(' ' * 6 + ' ' * len(text) +
''.join('{:^{}}'.format(bg, len(text)) for bg in range(40, 48)))
for fg in range(30, 38):
for bold in False, True:
fg_code = ('1;' if bold else '') + str(fg)
print(' {:>4} '.format(fg_code) + formatstring.format(fg_code) +
''.join(formatstring.format(fg_code + ';' + str(bg))
for bg in range(40, 48)))
40 41 42 43 44 45 46 47
30 XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ
1;30 XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ
31 XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ
1;31 XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ
32 XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ
1;32 XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ
33 XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ
1;33 XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ
34 XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ
1;34 XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ
35 XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ
1;35 XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ
36 XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ
1;36 XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ
37 XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ
1;37 XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ XYZ
ANSI also supports a set of 256 indexed colors. The following code showing all of them is based on http://bitmote.com/index.php?post/2012/11/19/Using-ANSI-Color-Codes-to-Colorize-Your-Bash-Prompt-on-Linux.
[33]:
formatstring = '\x1b[38;5;{0};48;5;{0}mX\x1b[1mX\x1b[m'
print(' + ' + ''.join('{:2}'.format(i) for i in range(36)))
print(' 0 ' + ''.join(formatstring.format(i) for i in range(16)))
for i in range(7):
i = i * 36 + 16
print('{:3} '.format(i) + ''.join(formatstring.format(i + j)
for j in range(36) if i + j < 256))
+ 0 1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829303132333435
0 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
16 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
52 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
88 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
124 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
160 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
196 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
232 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
You can even use 24-bit RGB colors:
[34]:
start = 255, 0, 0
end = 0, 0, 255
length = 79
out = []
for i in range(length):
rgb = [start[c] + int(i * (end[c] - start[c]) / length) for c in range(3)]
out.append('\x1b['
'38;2;{rgb[2]};{rgb[1]};{rgb[0]};'
'48;2;{rgb[0]};{rgb[1]};{rgb[2]}mX\x1b[m'.format(rgb=rgb))
print(''.join(out))
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX