如何实现Pandas DataFrame多行共用同一索引并垂直显示,生成类Excel格式表格
Hey there! Let's fix up your table to meet your requirements—vertical index display and every 3 consecutive rows sharing the same index. Here's a step-by-step solution with modified code:
Step 1: Key Adjustments Needed
Your original code generates a basic table, but we need two critical tweaks:
- Add the index as a dedicated column with vertically aligned text
- Merge cells in the index column for every 3 rows to create the shared-index effect
Step 2: Modified Code Implementation
We'll update the render_mpl_table function to handle vertical text and cell merging, then create a DataFrame with grouped indices.
import os import numpy as np import pandas as pd import matplotlib.pyplot as plt import math from IPython.core.interactiveshell import InteractiveShell InteractiveShell.ast_node_interactivity = "all" def render_mpl_table(data, col_width=3.0, row_height=0.625, font_size=14, header_color='#40466e', row_colors=['#f1f1f2', 'w'], edge_color='w', bbox=[0, 0, 1, 1], header_columns=0, ax=None, index_vertical=True, group_rows=3, **kwargs): if ax is None: # Account for the extra index column in figure size size = (np.array(data.shape[::-1]) + np.array([1, 1])) * np.array([col_width, row_height]) fig, ax = plt.subplots(figsize=size) ax.axis('off') # Prepare table data including the index as the first column cell_text = [] for idx, row in data.iterrows(): cell_text.append([str(idx)] + list(row.values)) # Column labels: add "Index" for the first column col_labels = ['Index'] + list(data.columns) # Create the table mpl_table = ax.table(cellText=cell_text, bbox=bbox, colLabels=col_labels, **kwargs) mpl_table.auto_set_font_size(False) mpl_table.set_fontsize(font_size) # Style cells for k, cell in mpl_table._cells.items(): cell.set_edgecolor(edge_color) # Style header row if k[0] == 0: cell.set_text_props(weight='bold', color='w') cell.set_facecolor(header_color) else: # Alternate row background colors cell.set_facecolor(row_colors[(k[0]-1)%len(row_colors)]) # Set vertical text for index column if index_vertical and k[1] == 0: cell.set_text_props(rotation=90, ha='center', va='center') # Merge index cells for every `group_rows` rows if group_rows > 1: total_rows = len(data) num_groups = total_rows // group_rows for group_idx in range(num_groups): start_row = group_idx * group_rows + 1 # Header is row 0, data starts at row 1 end_row = start_row + group_rows - 1 # Set height of the first cell in the group to cover all 3 rows mpl_table[start_row, 0].set_height(group_rows * row_height) # Hide the subsequent cells in the same index group for row in range(start_row + 1, end_row + 1): mpl_table[row, 0].set_visible(False) return ax.get_figure(), ax # Create a DataFrame with grouped indices (every 3 rows share the same index) df = pd.DataFrame({ 'Planet': ['Earth','Mercury', 'Jupiter', 'Mars', 'Venus', 'Saturn'], 'time': [2200, 2100, 1500, 2000, 1900, 1600], 'distance': [8, 7.5, 8.2, 9, 7.8, 8.5], 'Bz': [9,8, 10, 7, 6, 11] }, index=[0,0,0,1,1,1]) # Generate the table fig, ax = render_mpl_table(df, header_columns=0, col_width=2.0, group_rows=3) plt.show()
Key Changes Breakdown
- Index as a Dedicated Column: We added the DataFrame's index as the first table column, making it easy to style and merge independently.
- Vertical Index Text: Using
rotation=90on the index column cells ensures text displays vertically, with center alignment for readability. - Shared Index Merging: For each group of 3 rows, we set the first index cell's height to cover all 3 rows, then hide the other two index cells in the group—this creates the seamless shared-index look you want.
- Scalable: To add more rows, just extend the
indexlist in the DataFrame (e.g.,[0,0,0,1,1,1,2,2,2]for 9 rows across 3 groups).
内容的提问来源于stack exchange,提问作者user11607936
相关产品推荐
相关产品推荐

