Dan Fiorino
Dan Fiorino

Reputation: 418

Rotating the column name for a Pandas DataFrame

I'm trying to make nicely formatted tables from pandas. Some of my column names are far too long. The cells for these columns are large cause the whole table to be a mess.

In my example, is it possible to rotate the column names as they are displayed?

data = [{'Way too long of a column to be reasonable':4,'Four?':4},
        {'Way too long of a column to be reasonable':5,'Four?':5}]
pd.DataFrame(data)

I would like to rotate the names of the columns as displayed here.

Upvotes: 20

Views: 14174

Answers (5)

Paul Rougieux
Paul Rougieux

Reputation: 11409

I placed @Bobain's nice answer into a function so I can re-use it throughout a notebook.

def format_vertical_headers(df):
    """Display a dataframe with vertical column headers"""
    styles = [dict(selector="th", props=[('width', '40px')]),
              dict(selector="th.col_heading",
                   props=[("writing-mode", "vertical-rl"),
                          ('transform', 'rotateZ(180deg)'), 
                          ('height', '290px'),
                          ('vertical-align', 'top')])]
    return (df.fillna('').style.set_table_styles(styles))

format_vertical_headers(pandas.DataFrame(data))

enter image description here

Upvotes: 6

Bobain
Bobain

Reputation: 176

Something like:

data = [{'Way too long of a column to be reasonable':4,'Four?':4},
        {'Way too long of a column to be reasonable':5,'Four?':5}]
dfoo = pd.DataFrame(data)
dfoo.style.set_table_styles(
    [dict(selector="th",props=[('max-width', '80px')]),
        dict(selector="th.col_heading",
                 props=[("writing-mode", "vertical-rl"), 
                        ('transform', 'rotateZ(-90deg)'),
                        ])]
)

is probably close to what you want:

enter image description here

see result here

Upvotes: 16

scottlittle
scottlittle

Reputation: 20912

Looking at the pybloqs source code for the accepted answer's solution, I was able to find out how to rotate the columns without installing pybloqs. Note that this also rotates the index, but I have added code to remove those.

from IPython.display import HTML, display

data = [{'Way too long of a column to be reasonable':4,'Four?':4},
        {'Way too long of a column to be reasonable':5,'Four?':5}]
df = pd.DataFrame(data)

styles = [
    dict(selector="th", props=[("font-size", "125%"),
                               ("text-align", "center"),
                              ("transform", "translate(0%,-30%) rotate(-5deg)")
                              ]),
    dict(selector=".row_heading, .blank", props= [('display', 'none;')])
]

html = df.style.set_table_styles(styles).render()
display(HTML(html))

enter image description here

Upvotes: 4

Dan Fiorino
Dan Fiorino

Reputation: 418

Using the Python library 'pybloqs' (http://pybloqs.readthedocs.io/en/latest/), it is possible to rotate the column names as well as add a padding to the top. The only downside (as the documentation mentions) is that the top-padding does not work inline with Jupyter. The table must be exported.

import pandas as pd
from pybloqs import Block
import pybloqs.block.table_formatters as tf
from IPython.core.display import display, HTML

data = [{'Way too long of a column to be reasonable':4,'Four?':4},
        {'Way too long of a column to be reasonable':5,'Four?':5}]
dfoo =pd.DataFrame(data)

fmt_header = tf.FmtHeader(fixed_width='5cm',index_width='10%', 
                          top_padding='10cm', rotate_deg=60)
table_block = Block(dfoo, formatters=[fmt_header])

display(HTML(table_block.render_html()))
table_block.save('Table.html')

Table in HTML with rotated column names

Upvotes: 2

Louise Davies
Louise Davies

Reputation: 15961

I can get it so that the text is completely turned around 90 degrees, but can't figure out how to use text-orientation: upright as it just makes the text invisible :( You were missing the writing-mode property that has to be set for text-orientation to have any effect. Also, I made it only apply to column headings by modifying the selector a little.

dfoo.style.set_table_styles([dict(selector="th.col_heading",props=[("writing-mode", "vertical-lr"),('text-orientation', 'upright')])])

Hopefully this gets you a little closer to your goal!

Upvotes: 1

Related Questions