在您的示例中,您正在定义一个 2x1 子图,并且仅循环通过创建的两个轴对象。在这两个循环中的每一个中,当您调用df[col_pat_columns].plot(x='Week',ax=ax) 时,由于col_pat_columns 是一个列表并且您将其传递给df,因此您只是从数据框中绘制了多个列。这就是为什么它是一个情节上的多个系列。
@fdireito 是正确的——您只需将 plt.subplots() 的 ncols 参数设置为您需要的正确数字,但您需要调整循环以适应。
如果您想留在 matplotlib 中,那么这是一个基本示例。我不得不对您的数据框的结构等进行一些猜测。
# import matplotlib
import matplotlib.pyplot as plt
# create some fake data
x = [1, 2, 3, 4, 5]
df = pd.DataFrame({
'a':[1, 1, 1, 1, 1], # horizontal line
'b':[3, 6, 9, 6, 3], # pyramid
'c':[4, 8, 12, 16, 20], # steep line
'd':[1, 10, 3, 13, 5] # zig-zag
})
# a list of lists, where each inner list is a set of
# columns we want in the same row of subplots
col_patterns = [['a', 'b', 'c'], ['b', 'c', 'd']]
以下是您的代码最终执行的简化示例。
fig, axes = plt.subplots(len(col_patterns), 1)
for pat, ax in zip(col_patterns, axes):
ax.plot(x, df[pat])
2x1 subplot (what you have right now)
我使用enumerate() 和col_patterns 来遍历子图行,然后使用enumerate() 和给定模式中的每个列名来遍历子图列。
# the following will size your subplots according to
# - number of different column patterns you want matched (rows)
# - largest number of columns in a given column pattern (columns)
subplot_rows = len(col_patterns)
subplot_cols = max([len(x) for x in col_patterns])
fig, axes = plt.subplots(subplot_rows, subplot_cols)
for nrow, pat in enumerate(col_patterns):
for ncol, col in enumerate(pat):
axes[nrow][ncol].plot(x, df[col])
Correctly sized subplot
这是所有代码,为简单起见,我从上面的代码中省略了一些附加内容。
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
df = pd.DataFrame({
'a':[1, 1, 1, 1, 1], # horizontal line
'b':[3, 6, 9, 6, 3], # pyramid
'c':[4, 8, 12, 16, 20], # steep line
'd':[1, 10, 3, 13, 5] # zig-zag
})
col_patterns = [['a', 'b', 'c'], ['b', 'c', 'd']]
# what you have now
fig, axes = plt.subplots(len(col_patterns), 1, figsize=(12, 8))
for pat, ax in zip(col_patterns, axes):
ax.plot(x, df[pat])
ax.legend(pat, loc='upper left')
# what I think you want
subplot_rows = len(col_patterns)
subplot_cols = max([len(x) for x in col_patterns])
fig, axes = plt.subplots(subplot_rows, subplot_cols, figsize=(16, 8), sharex=True, sharey=True, tight_layout=True)
for nrow, pat in enumerate(col_patterns):
for ncol, col in enumerate(pat):
axes[nrow][ncol].plot(x, df[col], label=col)
axes[nrow][ncol].legend(loc='upper left')
您可以考虑的另一个选择是放弃 matplotlib 并使用 Seaborn relplots。该页面上有几个示例应该有所帮助。如果您的数据框设置正确(长或“整齐”的格式),那么要实现与上述相同的效果,您的单线将如下所示:
# import seaborn as sns
sns.relplot(data=df, kind='line', x=x_vals, y=y_vals, row=col_pattern, col=num_weeks_rolling)