按月-年的散点图矩阵
Matrix of scatterplots by month-year
我的数据位于两列的数据框中:y 和 x。数据指的是过去几年。虚拟数据如下:
np.random.seed(167)
rng = pd.date_range('2017-04-03', periods=365*3)
df = pd.DataFrame(
{"y": np.cumsum([np.random.uniform(-0.01, 0.01) for _ in range(365*3)]),
"x": np.cumsum([np.random.uniform(-0.01, 0.01) for _ in range(365*3)])
}, index=rng
)
在第一次尝试中,我使用以下代码绘制了 Seaborn 的散点图:
import seaborn as sns
import matplotlib.pyplot as plt
def plot_scatter(data, title, figsize):
fig, ax = plt.subplots(figsize=figsize)
ax.set_title(title)
sns.scatterplot(data=data,
x=data['x'],
y=data['y'])
plot_scatter(data=df, title='dummy title', figsize=(10,7))
但是,我想生成一个包含 12 个散点图的 4x3 矩阵,每个月一个,以年份为色调。我想我可以在我的数据框中创建第三列来告诉我年份,我尝试了以下操作:
import seaborn as sns
import matplotlib.pyplot as plt
def plot_scatter(data, title, figsize):
fig, ax = plt.subplots(figsize=figsize)
ax.set_title(title)
sns.scatterplot(data=data,
x=data['x'],
y=data['y'],
hue=data.iloc[:, 2])
df['year'] = df.index.year
plot_scatter(data=df, title='dummy title', figsize=(10,7))
虽然这让我可以看到年份,但它仍然在同一个散点图中显示所有数据,而不是创建多个散点图,每个月一个,所以它没有提供我需要的详细程度。
我可以按月对数据进行切片并构建一个 for 循环,每月绘制一个散点图,但实际上我想要一个矩阵,其中所有散点图都使用相似的轴刻度。有谁知道实现该目标的有效方法?
为了一次创建多个子图,seaborn 引入了 figure-level functions。 col=
参数指示应使用数据帧的哪一列来标识子图。 col_wrap=
可用于判断在开始另一行之前有多少子图彼此相邻。
请注意,您不应创建 figure
,因为函数会创建自己的新图形。它使用 height=
和 aspect=
参数来说明各个子图的大小。
下面的代码在月份上使用了 sns.relplot()
。为月份创建了一个额外的列;定单是明确的。
要删除标题中的 month=
,您可以遍历生成的轴(axes_dict
需要最新的 seaborn 版本)。使用 sns.set(font_scale=...)
您可以更改所有文本的默认大小。
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
np.random.seed(167)
dates = pd.date_range('2017-04-03', periods=365 * 3, freq='D')
df = pd.DataFrame({"y": np.cumsum([np.random.uniform(-0.01, 0.01) for _ in range(365 * 3)]),
"x": np.cumsum([np.random.uniform(-0.01, 0.01) for _ in range(365 * 3)])
}, index=dates)
df['year'] = df.index.year
month_names = pd.date_range('2017-01-01', periods=12, freq='M').strftime('%B')
df['month'] = pd.Categorical.from_codes(df.index.month - 1, month_names)
sns.set(font_scale=1.7)
g = sns.relplot(kind='scatter', data=df, x='x', y='y', hue='year', col='month', col_wrap=4, height=4, aspect=1)
# optionally remove the `month=` in the title
for name, ax in g.axes_dict.items():
ax.set_title(name)
plt.setp(g.axes, xlabel='', ylabel='') # remove all x and y labels
g.axes[-2].set_xlabel('x', loc='left') # set an x label at the left of the second to last subplot
g.axes[4].set_ylabel('y') # set a y label to 5th subplot
plt.subplots_adjust(left=0.06, bottom=0.06) # set some more spacing at the left and bottom
plt.show()
我的数据位于两列的数据框中:y 和 x。数据指的是过去几年。虚拟数据如下:
np.random.seed(167)
rng = pd.date_range('2017-04-03', periods=365*3)
df = pd.DataFrame(
{"y": np.cumsum([np.random.uniform(-0.01, 0.01) for _ in range(365*3)]),
"x": np.cumsum([np.random.uniform(-0.01, 0.01) for _ in range(365*3)])
}, index=rng
)
在第一次尝试中,我使用以下代码绘制了 Seaborn 的散点图:
import seaborn as sns
import matplotlib.pyplot as plt
def plot_scatter(data, title, figsize):
fig, ax = plt.subplots(figsize=figsize)
ax.set_title(title)
sns.scatterplot(data=data,
x=data['x'],
y=data['y'])
plot_scatter(data=df, title='dummy title', figsize=(10,7))
import seaborn as sns
import matplotlib.pyplot as plt
def plot_scatter(data, title, figsize):
fig, ax = plt.subplots(figsize=figsize)
ax.set_title(title)
sns.scatterplot(data=data,
x=data['x'],
y=data['y'],
hue=data.iloc[:, 2])
df['year'] = df.index.year
plot_scatter(data=df, title='dummy title', figsize=(10,7))
我可以按月对数据进行切片并构建一个 for 循环,每月绘制一个散点图,但实际上我想要一个矩阵,其中所有散点图都使用相似的轴刻度。有谁知道实现该目标的有效方法?
为了一次创建多个子图,seaborn 引入了 figure-level functions。 col=
参数指示应使用数据帧的哪一列来标识子图。 col_wrap=
可用于判断在开始另一行之前有多少子图彼此相邻。
请注意,您不应创建 figure
,因为函数会创建自己的新图形。它使用 height=
和 aspect=
参数来说明各个子图的大小。
下面的代码在月份上使用了 sns.relplot()
。为月份创建了一个额外的列;定单是明确的。
要删除标题中的 month=
,您可以遍历生成的轴(axes_dict
需要最新的 seaborn 版本)。使用 sns.set(font_scale=...)
您可以更改所有文本的默认大小。
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
np.random.seed(167)
dates = pd.date_range('2017-04-03', periods=365 * 3, freq='D')
df = pd.DataFrame({"y": np.cumsum([np.random.uniform(-0.01, 0.01) for _ in range(365 * 3)]),
"x": np.cumsum([np.random.uniform(-0.01, 0.01) for _ in range(365 * 3)])
}, index=dates)
df['year'] = df.index.year
month_names = pd.date_range('2017-01-01', periods=12, freq='M').strftime('%B')
df['month'] = pd.Categorical.from_codes(df.index.month - 1, month_names)
sns.set(font_scale=1.7)
g = sns.relplot(kind='scatter', data=df, x='x', y='y', hue='year', col='month', col_wrap=4, height=4, aspect=1)
# optionally remove the `month=` in the title
for name, ax in g.axes_dict.items():
ax.set_title(name)
plt.setp(g.axes, xlabel='', ylabel='') # remove all x and y labels
g.axes[-2].set_xlabel('x', loc='left') # set an x label at the left of the second to last subplot
g.axes[4].set_ylabel('y') # set a y label to 5th subplot
plt.subplots_adjust(left=0.06, bottom=0.06) # set some more spacing at the left and bottom
plt.show()