ipython: how to set terminal width

2019-03-11 20:52发布

问题:

When I use ipython terminal and want to print a numpy.ndarray which has many columns, the lines are automatically broken somewhere around 80 characters (i.e. the width of the lines is cca 80 chars):

z = zeros((2,20))
print z

Presumably, ipython expects that my terminal has 80 columns. In fact however, my terminal has width of 176 characters and I would like to use the full width.

I have tried changing the following parameter, but this has no effect:

c.PlainTextFormatter.max_width = 160

How can I tell ipython to use full width of my terminal ?

I am using ipython 1.2.1 on Debian Wheezy

回答1:

After some digging through the code, it appears that the variable you're looking for is numpy.core.arrayprint._line_width, which is 75 by default. Setting it to 160 worked for me:

>>> numpy.zeros((2, 20))
array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0., 0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]])

The function used by default for array formatting is numpy.core.numeric.array_repr, although you can change this with numpy.core.numeric.set_string_function.



回答2:

You can see your current line width with

numpy.get_printoptions()['linewidth']

and set it with

numpy.set_printoptions(linewidth=160)

Automatically set printing width

If you'd like the terminal width to be set automatically, you can have Python execute a startup script. So create a file ~/.python_startup.py or whatever you want to call it, with this inside it:

# Set the printing width to the current terminal width for NumPy.
#
# Note: if you change the terminal's width after starting Python,
#       it will not update the printing width.
from os import getenv
terminal_width = getenv('COLUMNS')
try:
    terminal_width = int(terminal_width)
except (ValueError, TypeError):
    print('Sorry, I was unable to read your COLUMNS environment variable')
    terminal_width = None

if terminal_width is not None and terminal_width > 0:
    from numpy import set_printoptions
    set_printoptions(linewidth = terminal_width)

del terminal_width

and to have Python execute this every time, open your ~/.bashrc file, and add

# Instruct Python to execute a start up script
export PYTHONSTARTUP=$HOME/.python_startup.py
# Ensure that the startup script will be able to access COLUMNS
export COLUMNS


回答3:

To automatically resize both numpy and IPython whenever your window size changes, add the following to your ipython_config.py:

import IPython
import signal
import shutil
import sys
try:
    import numpy as np
except ImportError:
    pass

c = get_config()

def update_terminal_width(*ignored):
    """Resize the IPython and numpy printing width to match the terminal."""
    w, h = shutil.get_terminal_size()

    config = IPython.get_ipython().config
    config.PlainTextFormatter.max_width = w - 1
    shell = IPython.core.interactiveshell.InteractiveShell.instance()
    shell.init_display_formatter()

    if 'numpy' in sys.modules:
        import numpy as np
        np.set_printoptions(linewidth=w - 5)

# We need to configure IPython here differently because get_ipython() does not
# yet exist.
w, h = shutil.get_terminal_size()
c.PlainTextFormatter.max_width = w - 1
if 'numpy' in sys.modules:
    import numpy as np
    np.set_printoptions(linewidth=w - 5)

signal.signal(signal.SIGWINCH, update_terminal_width)

If you want to delay loading numpy until necessary, look at Post import hooks in Python 3 for a solution.

If you're not using IPython, put the above in your PYTHONSTARTUP file and remove the IPython-specific lines.