Black Lives Matter. Please consider donating to Black Girls Code today.
Learn how to use COVID-19 data in open source Dash apps. Register for the Sept 23rd webinar with IQT!

Gantt cropped text

Hello :),

I’m preparing a demonstration with tons of graph and tables to show what I can do with Python for future job interviews.
So I tried to do a Gantt chart with a list of students entering and exiting a language school at different dates. The data was recognized as expected. Except the text of the y axis is cropped and will only display about 11 characters.
I’ve tried to fix the problem without success:

  • I’ve read the help of iplot and gantt_chart to see if I was missing an argument. Tried modifying the width of the chart but it doesn’t change the width of the y axis
  • I’ve tried adding an angle to the y axis. This did work with angles over 40° or something but it doesn’t look good in this example. Besides I’m looking for a more universal solution to accept like 50 characters without a problem.
  • I’ve tried modifying the jupyter’s notebook width to 100%. The notebook did change but not the graph.

Note: Initials or abbreviations could be considered but in this example it would be impractical. Also there are much more than 6 students in the final demonstration.

I’d like to point out that the example of plotly itself suffers the same issue: see page https://plot.ly/python/gantt/ look at the output n°7 the M of morning sleep is cropped.

Does anybody have an idea :roll_eyes: ?

Code:

import pandas as pd
from plotly.offline import init_notebook_mode, iplot
from plotly.graph_objs import *
init_notebook_mode(connected=True)  # initiate notebook for offline plot
import plotly.figure_factory as ff
df_gantt2 =pd.DataFrame([
{'Task': 'Anthony Clark', 'Start': '2017-12-13', 'Finish': '2018-02-23'},
{'Task': 'Ariosto Li Fonti', 'Start': '2017-12-15', 'Finish': '2018-01-23'},
{'Task': 'Cettina Trevisano', 'Start': '2017-12-20', 'Finish': '2018-03-08'},
{'Task': 'Dora Padovesi', 'Start': '2018-01-11', 'Finish': '2018-01-12'},
{'Task': 'Emmeline Déziel', 'Start': '2018-01-22', 'Finish': '2018-03-25'},
{'Task': 'Sawa Tretyakov', 'Start': '2018-12-03', 'Finish': '2018-12-31'},])

fig = ff.create_gantt(df_gantt2, colors=['#333F44', '#93e4c1'],title='Students\' presence (those are fake names)',show_colorbar=True, bar_width=0.2, showgrid_x=True, showgrid_y=True)
iplot(fig,filename = 'students-presence-gantt')

Result:

Hey @Thib,
The following fig['layout'] update removes the reported issue:

   fig['layout'].update(autosize=False, width=800, height=500, margin=dict(l=110))

Insert this line just after fig=ff.create_gantt
You can read more on margin here https://plot.ly/python/reference/#layout-margin

3 Likes

Thanks a lot that solved the issue !!!

So hum I kind of did this programmatically :robot::robot:. Here is the function:

EDIT: I can’t indent the function properly here (should be 4 additional spaces everywhere after the first line) so don’t forget that.

def max_length_col(column,font='OpenSans-Regular.ttf', font_size=14):
'''Calculates the max length of a column of a dataframe / a panda serie in pixels.
Default keyword arguments values are useful to adapt the length of the y axis of a plotly gantt chart.  

Args:
    column: panda serie
    font: ttf filename (look under ...\Windows\Font, get the exact name by right-clicking on a ttf file and then go to properties)
    font_size : font size as an int
    
Example:
    In:
        df_gantt =pd.DataFrame([
        {'Task': 'Anthony Clark', 'Start': '2017-12-13', 'Finish': '2018-02-23'},
        {'Task': 'Ariosto Li Fonti', 'Start': '2017-12-15', 'Finish': '2018-01-23'},
        {'Task': 'Cettina Trevisano', 'Start': '2017-12-20', 'Finish': '2018-03-08'}])
        column_len = max_length_col(df_gantt['Task'])
        print(column_len)
    Out:
        117

Returns:
    Length of the column in pixel as an int
'''
from PIL import ImageFont #pip install pillow
font = ImageFont.truetype(font,font_size) # should already be installed, if not download it and save under Windows/Font
length_list = []
for row in range(len(column)):
    text = str(column[row])
    size = font.getsize(text)
    length_list.append(size[0]) # append length in pixel (size[1] for heigth)
max_length_px = max(length_list)
return max_length_px

Here is the updated file by the way (I added other students in there).

1 Like