[英]Plot subplots inside subplots matplotlib
背景:我想 plot 多个子图(由图例分隔)基于子图中 dataframe 列中的模式但是,我无法将每个子图分成另一组子图。
这就是我所拥有的:
import matplotlib.pyplot as plt
col_patterns = ['pattern1','pattern2']
# define subplot grid
fig, axs = plt.subplots(nrows=len(col_patterns), ncols=1, figsize=(30, 80))
plt.subplots_adjust()
fig.suptitle("Title", fontsize=18, y=0.95)
for col_pat,ax in zip(col_patterns,axs.ravel()):
col_pat_columns = [col for col in df.columns if col_pat in col]
df[col_pat_columns].plot(x='Week',ax=ax)
# chart formatting
ax.set_title(col_pat.upper())
ax.set_xlabel("")
结果是这样的:
我怎样才能使这些子图中的每一个都变成另外 6 个子图,全部水平布置? (即每个图例都是它自己的子图)
谢谢!
在您的示例中,您定义了一个 2x1 子图,并且仅循环通过创建的两个轴对象。 在这两个循环中的每一个中,当您调用df[col_pat_columns].plot(x='Week',ax=ax)
时,由于col_pat_columns
是一个列表并且您将其传递给df
,您只是从你的 dataframe。 这就是为什么它在单个 plot 上有多个系列。
@fdireito 是正确的——您只需将plt.subplots()
的ncols
参数设置为您需要的正确数字,但您需要调整循环以适应。
如果你想留在matplotlib,那么这里有一个基本的例子。 我不得不猜测您的 dataframe 的结构等等。
# 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])
我使用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])
这是所有代码,为简单起见,我从上面的代码中省略了一些附加内容。
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 。 该页面上有几个示例应该有所帮助。 如果您的 dataframe 设置正确(长或“整齐”的格式),那么要实现与上述相同的效果,您的单线将如下所示:
# import seaborn as sns
sns.relplot(data=df, kind='line', x=x_vals, y=y_vals, row=col_pattern, col=num_weeks_rolling)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.