Rabarberski
Rabarberski

Reputation: 24942

Is it possible to print using different colors in ipython's Notebook?

Is it somehow possible to have certain output appear in a different color in the IPython Notebook? For example, something along the lines of:

 print("Hello Red World", color='red')

Upvotes: 104

Views: 103982

Answers (15)

Nikhil G
Nikhil G

Reputation: 559

In the Jupiter notebook, we can use a color marker to print the output in different colors There are three ways that we can use a color marker.

let's see how to print a yellow color in a notebook.

  1. print('\033[93m output')
  2. print('\033[93m' 'output')
  3. print('\033[93m' + 'output')

Some of the colors are :

  • yellow = '\033[93m'
  • green = '\033[92m'
  • red = '\033[91m'
  • blue = '\033[94m'
  • pink = '\033[95m'

you can change the last number and get other colors as well.

Note: to return to default color use: \033[0m

enter image description here

Upvotes: 35

Rumpelstiltskin Koriat
Rumpelstiltskin Koriat

Reputation: 421

A slightly more "productized" version of @alvas's great answer:

expected output



import re
from IPython.core.display import display, HTML


def color_needle(needle: str, text: str) -> HTML:
  if not re.search(needle, text):
    return HTML(text)

  match_substr = re.search(f"({needle})", text).group(1)
  text = re.sub(match_substr, cstr(match_substr, "red"), text)
  return HTML(text)


display(color_needle("n..dle", "find a needle in a haystack of needles"))

Upvotes: 0

Brian
Brian

Reputation: 63

As suggested, the exact behavior you are asking for can be achieved by wrapping the print() function like so:

def print_wrapper(func):
    ansi_reset = '\033[0m'
    ansi_black = '\033[90m'
    ansi_red = '\033[91m'
    ansi_green = '\033[92m'
    ansi_yellow = '\033[93m'
    ansi_blue = '\033[94m'
    ansi_pink = '\033[95m'
    ansi_teal = '\033[96m'
    ansi_gray = '\033[97m'
    ansi_warning = '\033[31;1;4m'
    ansi_error = '\033[31;100m'
    def wrapped_func(*args,**kwargs):
        new_args = args + tuple()
        new_kwargs = kwargs.copy()
        for kwarg, kwvalue in kwargs.items(): # Loop through the keyword arguments
            if kwarg == "color":
                if kwvalue == "black":
                    color = ansi_black
                elif kwvalue == "red":
                    color = ansi_red
                elif kwvalue == "green":
                    color = ansi_green
                elif kwvalue == "yellow":
                    color = ansi_yellow
                elif kwvalue == "blue":
                    color = ansi_blue
                elif kwvalue == "pink":
                    color = ansi_pink
                elif kwvalue == "teal":
                    color = ansi_teal
                elif kwvalue == "gray":
                    color = ansi_gray
                elif kwvalue == "warning":
                    color = ansi_warning
                elif kwvalue == "error":
                    color = ansi_error
                new_kwargs = kwargs.copy() # Make a copy of the keyword arguments dict
                del new_kwargs["color"] # Remove color from the keyword arguments dict
        try: # Is the variable color defined?
            color
        except NameError:
            pass
            # no color was specified
        else:
            new_args = ()
            for arg in args:
                new_args += (f"{color}{arg}{ansi_reset}",) # Apply the ANSI escape codes to each non-keyword argument
        return func(*new_args,**new_kwargs)
    return wrapped_func

print = print_wrapper(print) # Apply the wrapper to the print() function

print("This is red.", "And so is this.", color='red')

This solution uses the ANSI escape sequences mentioned in several other answers here, but parses and modifies the arguments to print() before outputting them.

Upvotes: 0

Alex
Alex

Reputation: 3451

A nice way is to use pandas:

import pandas as pd
def apply_formatting(col, hex_colors):
    for hex_color in hex_colors:
        if col.name == hex_color:
            return [f'background-color: {hex_color}' for c in col.values]
                
def display_hex_colors(hex_colors: List[str]):
    df = pd.DataFrame(hex_colors).T
    df.columns = hex_colors
    df.iloc[0,0:len(hex_colors)] = ""
    display(df.style.apply(lambda x: apply_formatting(x, hex_colors)))
hex_list = ['#FFFFFF', '#F0F0F0', '#FCF0D8', '#fdd8a7', '#fdc38d', '#fca16c',
            '#f67b51', '#e7533a', '#cf2518', '#ad0000', '#7f0000', '#440402']
display_hex_colors(hex_list)

Example output: enter image description here

Upvotes: 3

Anand Tripathi
Anand Tripathi

Reputation: 16196

You can use this library termcolor and you can get all other official libraries of python in PyPi.

  1. pip install termcolor
  2. then goto ipython

Code

from termcolor import colored
print(colored('hello', 'red'), colored('world', 'green'))
print(colored("hello red world", 'red'))

Output:

hello world
hello red world

The first argument is what you want to print on console and second argument use that color.

See the documentation in pypi.python.org for more information

Upvotes: 64

Carlos B
Carlos B

Reputation: 466

Taken from: Standard for ANSI Colors in Terminals

This snippet can show you all the colors in one row:

RESET = "\x1b[0m"
print("To reset attributes: \\x1b[0m\n")
for i in range(0, 8):
    print("\x1b[1;3{0}m\\x1b[1;3{0}m{1} \x1b[0;3{0}m\\x1b[0;3{0}m{1} "
          "\x1b[1;4{0};3{0}m\\x1b[1;3{0};4{0}m{1}".format(i, RESET))

Upvotes: 1

Hrvoje
Hrvoje

Reputation: 15252

Text in red:

print("\x1b[31mText in red")

Text in bold:

print("\x1B[1mText in bold")

Text in underline

print("\x1B[4mText in underline")

See here under Styles and Colors chapter and see what works for you. RGB colors didn't work for me.

Upvotes: 4

miki
miki

Reputation: 659

Thanks to @alvas function and adding another function we get a very simple way to print

from IPython.display import HTML as html_print
from IPython.display import display

def cstr(s, color='black'):
    return "<text style=color:{}>{}</text>".format(color, s)

def print_color(t):
    display(html_print(' '.join([cstr(ti, color=ci) for ti,ci in t])))

print_color((('hello my name is', 'black'),('jhjfd','red')))
print_color((('hello my name is', 'green'),))

enter image description here

Upvotes: 6

Zags
Zags

Reputation: 41358

There is the colored library (pip install colored), which you can use to modify a string to get color codes to modify how it is printed. Example use:

import colored
print(colored.bg("white") + colored.fg("red") + "Hello world!")

Upvotes: 10

finiteautomata
finiteautomata

Reputation: 3813

colorama makes it dead easy:

from colorama import Fore
print(Fore.RED + "this is red")

Upvotes: 5

Kourosh Meshgi
Kourosh Meshgi

Reputation: 532

Similar to what @alvas mentioned but simpler

from IPython.display import Markdown
display (Markdown('this is in <span style="color: #ff0000">red</span> color.'))

Upvotes: 39

Roei Bahumi
Roei Bahumi

Reputation: 3683

Using @Evert answer, here is a method that would wrap a list of tokens in red and return a highlighted string

def color_in_tokens(tokens, color_token_contains="_"):
  """
  Highlights the tokens which contain 'color_token_contains'

  :param tokens: list of strings
  :param color_token_contains: str (the string for marking a token red)
  :return: str
  """
  return " ".join(["\x1b[31m%s\x1b[0m" % i if color_token_contains in i else i for i in tokens])

Just call print on the returned string: enter image description here

Upvotes: 2

alvas
alvas

Reputation: 122330

Here's a quick hack:

from IPython.display import HTML as html_print

def cstr(s, color='black'):
    return "<text style=color:{}>{}</text>".format(color, s)

left, word, right = 'foo' , 'abc' , 'bar'
html_print(cstr(' '.join([left, cstr(word, color='red'), right]), color='black') )

[out]:

enter image description here

If you just want a single color: html_print(cstr('abc', 'red'))

Upvotes: 38

user707650
user707650

Reputation:

The notebook has, of course, its own syntax highlighting. So I would be careful when using colour elsewhere, just to avoid making things harder to read for yourself or someone else (e.g., output should simply be in black, but you get parts in red if there is an exception).

But (to my surprise), it appears that you can use ANSI escape codes (even in the browser). At least, I could:

On the default Python prompt:

>>> print("\x1b[31m\"red\"\x1b[0m")
"red"

In the notebook:

In [28]: print("\x1b[31m\"red\"\x1b[0m")
         "red"

(Obviously, I cheated here with the syntax highlighting of SO so that "red" is printed in the colour red in both examples. I don't think SO allows a user to set a colour for text.)

I wouldn't really know another way to get colours.

For more on ANSI escape codes, I'd suggest the Wikipedia article. And if you find the above to verbose, you can of course write a wrapper function around this.

Upvotes: 108

Matt
Matt

Reputation: 27853

Not with raw Python print. You will have to define a _repr_html_ on an object and return it or call IPython.lib.display(object_with_repr_html).

I guess you could overwrite the built-in print to do it automatically...

You could inspire from http://nbviewer.ipython.org/5098827, code in a gist on github, ML discussion here.

Upvotes: 14

Related Questions