我有一个
DataFrame
和成对的列。我想绘制它,使得每对列都有唯一的颜色,并且每对中的一列具有空填充。
我试过这个:
import pandas as pd
df = pd.DataFrame({
('A', '1'): [1, 2, 3],
('A', '2'): [4, 5, 6],
('B', '1'): [7, 8, 9],
('B', '2'): [10, 11, 12]
})
df.plot.bar(color=['C0', 'none', 'C1', 'none'], edgecolor=['C0', 'C0', 'C1', 'C1'])
这几乎可以工作了!但它按行而不是按列应用
edgecolor
。
我请求 ChatGPT 救救我。它给了我一个有效的解决方案(请参阅下面稍加修改的版本),但它非常冗长。我的问题是,有没有更简单的方法来做到这一点,最好使用
DataFrame.plot
?
import pandas as pd
import matplotlib.pyplot as plt
# Sample DataFrame
df = pd.DataFrame({
('A', '1'): [1, 2, 3],
('A', '2'): [4, 5, 6],
('B', '1'): [7, 8, 9],
('B', '2'): [10, 11, 12]
})
# Define colors for each pair
colors = ['C0', 'C1']
# Create a bar chart
fig, ax = plt.subplots()
# Number of columns
num_cols = len(df.columns)
# Bar width
bar_width = 0.2
# Plot each pair of columns
for i in range(0, num_cols, 2):
color_i = colors[i//2]
ax.bar(df.index + i*bar_width, df.iloc[:, i], bar_width,
label=str(df.columns[i]), color=color_i, edgecolor=color_i)
ax.bar(df.index + (i+1)*bar_width, df.iloc[:, i+1], bar_width,
label=str(df.columns[i+1]), color='none', edgecolor=color_i)
# Add labels, title, and legend
ax.set_xlabel('Index')
ax.set_ylabel('Values')
ax.set_title('Bar chart with paired columns')
ax.set_xticks(df.index + bar_width * (num_cols / 2 - 0.5))
ax.set_xticklabels(df.index)
ax.legend()
使用
np.repeat
重复每种颜色n 次,其中
n = len(df)
。通过 plt.patches.Patch.set_edgecolor
分配。随后使用
plt.legend
处理更新。
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
df = pd.DataFrame({
('A', '1'): [1, 2, 3],
('A', '2'): [4, 5, 6],
('B', '1'): [7, 8, 9],
('B', '2'): [10, 11, 12]
})
fig, ax = plt.subplots()
df.plot.bar(ax=ax, color=['C0', 'none', 'C1', 'none'])
edgecolors = np.repeat(['C0', 'C0', 'C1', 'C1'], len(df))
for edgecolor, patch in zip(edgecolors, ax.patches):
patch.set_edgecolor(edgecolor)
plt.legend()
plt.tight_layout()
plt.show()
剧情: