Estou procurando uma maneira de adicionar colunas que possam abranger várias linhas e linhas que possam abranger várias colunas.
Atualmente, tenho o código abaixo para inserir a primeira linha.
# Calculate log-scaled widths
table_widths = [0.001, 0.002, 0.063, 2.0, 63.0, 150.0]
log_table_widths = np.diff(np.log10(table_widths))
log_table_widths = log_table_widths / log_table_widths.sum()
# Normalize widths to sum to 1
log_table_widths = log_table_widths / log_table_widths.sum()
table = ax.table(cellText=[['Clay', 'Silt', 'Sand', 'Gravel', 'Cobbles']], cellLoc='center', loc='bottom', colWidths=log_table_widths)
table_widths = []
table.auto_set_font_size(False)
table.set_fontsize(8)
table.scale(1, 1.5)
Para obter o seguinte resultado:
No entanto, preciso adicionar outra linha à tabela que terá algumas colunas abrangendo a próxima linha. Enquanto as células na linha atual terão que abranger várias colunas. Assim:
De preferência com a linha inferior sendo a linha superior, mas não um desastre.
Tentei fazer isso sozinho e consegui ajuda do GitHub CoPilot e do MS CoPilot. No entanto, sem sorte, o melhor que conseguimos foi o seguinte:
# Calculate log-scaled widths
table_widths = [0.001, 0.002, 0.063, 2.0, 63.0, 150.0]
log_table_widths = np.diff(np.log10(table_widths))
log_table_widths = log_table_widths / log_table_widths.sum()
# Normalize widths to sum to 1
log_table_widths = log_table_widths / log_table_widths.sum()
# Create the table
cell_text = [
['Clay', 'Silt', 'Fine', 'Medium', 'Coarse', 'Fine', 'Medium', 'Coarse'],
['', '', 'Sand', 'Sand', 'Sand', 'Gravel', 'Gravel', 'Gravel'],
]
col_labels = ['Clay', 'Silt', 'Fine', 'Medium', 'Coarse', 'Fine', 'Medium', 'Coarse']
col_widths = [log_table_widths, log_table_widths, log_table_widths/3, log_table_widths/3, log_table_widths/3, log_table_widths/3, log_table_widths/3, log_table_widths/3]
# Add the table to the plot
table = ax.table(cellText=cell_text, colLabels=col_labels, cellLoc='center', loc='bottom', colWidths=col_widths)
table.auto_set_font_size(False)
table.set_fontsize(8)
table.scale(1, 1.5)
# Adjust cell alignment to avoid ambiguity
for key, cell in table.get_celld().items():
cell.set_text_props(ha='center', va='center')
Está me dando o seguinte erro:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
Sem nenhuma pista de como resolver.
Para reprodutibilidade você pode usar:
fig, ax = plt.subplots()
fig.set_figwidth(18)
fig.set_figheight(12)
fig.set_dpi(80)
# draw vertical line at: 0.002mm, 0.063mm, 2.0mm, 63mm
ax.axvline(x=0.002, color='red', linestyle='--')
ax.axvline(x=0.063, color='red', linestyle='--')
ax.axvline(x=2.0, color='red', linestyle='--')
ax.axvline(x=63.0, color='red', linestyle='--')
ax.set_xlim(0.001, 150)
# Calculate log-scaled widths
table_widths = [0.001, 0.002, 0.063, 2.0, 63.0, 150.0]
log_table_widths = np.diff(np.log10(table_widths))
log_table_widths = log_table_widths / log_table_widths.sum()
# Normalize widths to sum to 1
log_table_widths = log_table_widths / log_table_widths.sum()
# Create the table
cell_text = [
['Clay', 'Silt', 'Fine', 'Medium', 'Coarse', 'Fine', 'Medium', 'Coarse'],
['', '', 'Sand', 'Sand', 'Sand', 'Gravel', 'Gravel', 'Gravel'],
]
col_labels = ['Clay', 'Silt', 'Fine', 'Medium', 'Coarse', 'Fine', 'Medium', 'Coarse']
col_widths = [log_table_widths, log_table_widths, log_table_widths/3, log_table_widths/3, log_table_widths/3, log_table_widths/3, log_table_widths/3, log_table_widths/3]
# Add the table to the plot
table = ax.table(cellText=cell_text, colLabels=col_labels, cellLoc='center', loc='bottom', colWidths=col_widths)
table.auto_set_font_size(False)
table.set_fontsize(8)
table.scale(1, 1.5)
# Adjust cell alignment to avoid ambiguity
for key, cell in table.get_celld().items():
cell.set_text_props(ha='center', va='center')
fig.savefig('fig.png', format='png', bbox_inches='tight')
EDIT: Consegui me livrar do erro. Ele foi causado pela definição da variável col_widths onde eu estava preenchendo-a com listas em vez de seus valores correspondentes. Agora eu a defini assim, talvez encontre uma solução melhor para isso mais tarde.
col_widths = [log_table_widths[0], log_table_widths[1], log_table_widths[2] / 3, log_table_widths[2] / 3, log_table_widths[2] / 3, log_table_widths[3] / 3, log_table_widths[3] / 3, log_table_widths[3] / 3, log_table_widths[4]]
Minha tabela agora se parece com isso:
Embora eu não tenha descoberto como mesclar as linhas e células. Eu encontrei este post: Tabela Matplotlib com cabeçalhos duplos Onde várias tabelas são criadas para mostrar vários cabeçalhos. Mas isso, infelizmente, não funcionará para mesclar células em uma coluna e apenas uma linha.