使用循环生成多个子图

Posted

技术标签:

【中文标题】使用循环生成多个子图【英文标题】:Generate several subplots with a loop 【发布时间】:2021-12-18 03:10:51 【问题描述】:

我想在一个小图表中显示每年每个月的所有平均温度。我的第一个问题是打印较冷(蓝色)和较暖(分别为红色)温度的图例,并为图表本身着色。 我的第二个问题与循环数据有关,最终出现以下错误: TypeError: unsupported operand type(s) for /: 'tuple' and 'int'。年数不一定是偶数。我怎样才能在循环中很好地表示它?

我怎样才能把图表像下面的图片一样,包括彩色图例和图表。

我想要什么:

显示所有年份和每个月的所有平均温度 彩色图例和图表 (不管是 matloblib 还是 seaborn)
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
d = 'year': [2001, 2001, 2001, 2001, 
              2002, 2002, 2002, 2002],
     'month': [1, 2,3,4,
              1,2,3,4],
     'temperature': [10,20,15,20,
                     20,10,5,10]
df = pd.DataFrame(data=d)

df.head()


fig, axs = plt.subplots(int(len(df.year.unique()) / 2), int(len(df.year.unique()) / 2))

for i in enumerate(df.year.unique()):
    for j in range(int(i/2)):
        for k in range(int(i/2)):
            month = df['month'].unique()
            temperature = df[df['year'] == i].groupby('month')['temperature'].mean().values
            axs[j][k].bar(month, temperature)
plt.show()
    


TypeError: unsupported operand type(s) for /: 'tuple' and 'int'

【问题讨论】:

【参考方案1】:

Seaborn 及其 facetgrid 集成地块让您走得很远。像这样在行和列中绘制年份就像使用 col="year", col_wrap=10 一样简单。

在 seaborn 中,我们更喜欢使用启用了 facetgrid 的绘图功能,因为它们很灵活,就像这个例子中的 catplot 所示。

这是一个示例,需要填写一些随机数据

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

years = np.arange(1990, 2022, 1).reshape((-1, 1))
months = np.array([5, 6, 7, 8]).reshape((1, 4))
years, months = (np.broadcast_arrays(years, months))

d = 'year': years.flatten(),
     'month': months.flatten(),
     'temperature': np.random.randint(0, 25, size=years.size),
    
df = pd.DataFrame(data=d)



fg = sns.catplot(data=df, kind='bar', x='month', y='temperature', hue='temperature',
                 palette='Reds', col='year', col_wrap=10,
                 height=2, aspect=0.8, dodge=False, ci=None);
fg.set_titles(col_template="col_name");
fg.legend.remove()

# Hackily add a colorbar too
norm = plt.Normalize(df.temperature.min(), df.temperature.max())
sm = plt.cm.ScalarMappable(cmap="Reds", norm=norm)
sm.set_array([])

cax = fg.figure.add_axes([0.96, .12, .02, .8])
fg.figure.colorbar(sm, cax=cax);

fg 是我们可以用来访问各个轴并进行进一步调整的 facetgrid。所有轴都可以通过fg.axes 循环访问。

这里的绝对弱点是 seaborn 不支持按值连续着色(这是撰写本文时的未来项目,see this issue)。所以我们没有很好的色调插值,也没有自动连续的颜色条。

但是,我添加了一个颜色条解决方法 - 全部归功于 this answer。 必须说色调和颜色条并不完全同步。

【讨论】:

非常感谢,非常感谢!!是否可以选择自己确定调色板?让它从冷到暖(从蓝色到红色)? 我得到了AttributeError: 'FacetGrid' object has no attribute 'figure':/ 属性错误可能是您的版本稍旧。旧名称是 fig,但现在已弃用,取而代之的是 figure。调色板名称 - 'Reds',出现两次(对不起)决定了调色板。名称或其他颜色图对象应该可以工作。 非常感谢!! :) 是的,它是fig。必须升级它。谢谢!!

以上是关于使用循环生成多个子图的主要内容,如果未能解决你的问题,请参考以下文章

R语言ggplot2可视化分面图(faceting)编写自定义函数将生成的分面图分裂成多个子图并按照索引读取对应的可视化图像:Split facet plot into list of plots

生成多sitemap文件

poi根据模版生成多页word,并压缩下载

如何使用 numpy 生成多类测试数据集?

用Python或者Java如何生成多位数字不重复的数

如何鞋子批发生成多站点