我正在使用 Plotly 绘制不同大小的表格,并希望将其导出为图像。然而,绘图的大小不会随着表格大小自动缩放,导致图像中仅显示表格的一部分(或者如果我将绘图大小设置得太大,则会显示大量空白)。我知道我可以使布局的高度取决于行数,但这并不能解决问题,因为每行占用的空间也取决于实际的表格内容(例如大字符串将需要更多空间)。
import pandas as pd
import plotly.graph_objs as go
import plotly.offline as py
py.offline.init_notebook_mode()
import numpy as np
df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
trace = go.Table(
header=dict(values=df.columns,
fill = dict(color='#C2D4FF'),
align = ['left'] * 5),
cells=dict(values=[df.A, df.B, df.C, df.D],
fill = dict(color='#F5F8FF'),
align = ['left'] * 5))
layout = dict(autosize=True)
fig = go.Figure(data=[trace], layout=layout)
py.iplot(fig, show_link=False)
提前致谢。
这绝不是一个完美的解决方案,参数需要根据字体大小、列数和输入字符串的长度进行调整。但它确实能完成工作。
def calc_table_height(df, base=208, height_per_row=20, char_limit=30, height_padding=16.5):
'''
df: The dataframe with only the columns you want to plot
base: The base height of the table (header without any rows)
height_per_row: The height that one row requires
char_limit: If the length of a value crosses this limit, the row's height needs to be expanded to fit the value
height_padding: Extra height in a row when a length of value exceeds char_limit
'''
total_height = 0 + base
for x in range(df.shape[0]):
total_height += height_per_row
for y in range(df.shape[1]):
if len(str(df.iloc[x][y])) > char_limit:
total_height += height_padding
return total_height
如果您的
font_size
与默认值不同,或者您更改了默认值 margin
,您可能需要尝试其他功能。此外,该函数的 char_limit
参数是另一个弱点,因为某些字符比其他字符占用更多空间,大写字符占用更多空间,并且单个单词(如果很长)可能会强制延长一行。如果数量或列数较少,也应该增加,反之亦然。该函数以 4 个表列(这个问题)作为基线编写。
import pandas as pd
import plotly.graph_objs as go
import plotly.offline as py
py.offline.init_notebook_mode()
import numpy as np
df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
trace = go.Table(
header=dict(values=df.columns,
fill = dict(color='#C2D4FF'),
align = ['left'] * 5),
cells=dict(values=[df.A, df.B, df.C, df.D],
fill = dict(color='#F5F8FF'),
align = ['left'] * 5))
layout = dict(height=calc_table_height(df)) #This is changed
fig = go.Figure(data=[trace], layout=layout)
py.iplot(fig, show_link=False)
我遇到了同样的问题,最终做出了完全适合我的表格布局的功能。 该方法的独特之处在于它在每个单元格的一行中打印所有数据。 但对于不太长的字符串来说看起来还可以。
您可以使用
char_width
和其他常量。但我通过实验得到的这个值是最好的。
完整代码:
import numpy as np
import pandas as pd
import plotly.graph_objects as go
df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
title = 'My table'
# set used font width
char_width = 10
header_char_width = 11
# Max length of each column
max_len = df.astype(str).apply(lambda x: x.str.len()).max()
column_widths = [int(max_len[col] * char_width) for col in df.columns]
# Check if headers longer than data
column_widths = [max(column_widths[i], len(df.columns[i]) * header_char_width, 4*char_width) for i in range(len(df.columns))]
# Create go.Table
table = go.Table(
header=dict(values=list(df.columns),
font=dict(size=14)),
cells=dict(values=df.values.transpose(),
height = 25), # default height for each row
columnwidth=column_widths
)
# Calc layout size
l_width = max(sum(column_widths) + 100, len(title)*11) # check if title is longer than table
l_height = 250 + (df.shape[0] * 25) # height based on row count + space for layout
layout = go.Layout(
height=l_height,
width=l_width,
title=title
)
fig = go.Figure(data=[table], layout=layout)
fig.show()