具有 2 个 y 轴的分组箱线图,每个 x 刻度 2 个绘制变量
Grouped boxplot with 2 y axes, 2 plotted variables per x tick
我正在尝试绘制 18 年月降雨量和洪水频率记录的箱线图。即每个 x 刻度是月份,每个 x 刻度与两个箱线图相关联,一个是降雨量,一个是洪水频率。到目前为止,我已经设法使用 seaborn 绘制了这些图(请参见以下代码和图像),但是我不知道如何创建具有两个 y 轴的箱线图,我需要它,因为每个变量的比例不同。
数据如下(数据集中flood_freq的最大值为7,此处未显示):
Group Rainfall Flood_freq
0 Jan 115.679997 0
1 Jan 72.929999 0
2 Jan 39.719999 0
3 Jan 46.799999 1
4 Jan 54.989998 0
...
212 Dec 51.599998 0
213 Dec 45.359999 0
214 Dec 10.260000 0
215 Dec 52.709998 0
这是我用过的代码:
dd=pd.melt(FBPdf,id_vars=['Group'],value_vars=['Rainfall','Flood_freq'],var_name='Data')
sns.boxplot(x='Group',y='value',data=dd,hue='Data')
结果是:
从那以后我查看了 seaborn 文档,它似乎不允许 2 个 y 轴 ()。有没有人能够为我想要实现的目标提供潜在的替代方案?上面 link 上的解决方案与我遇到的这个双 y 轴和分组箱线图问题无关。
非常感谢您!
借助一些虚假数据和 this tutorial and this answer 的一点帮助,这里有一个简单的示例,说明如何仅使用 numpy
和 matplotlib
:
来实现您想要的效果
from matplotlib import pyplot as plt
import numpy as np
rainfall = np.random.rand((12*18))*300
floods = np.random.rand((12*18))*2
t = np.arange(0.01, 10.0, 0.01)
data1 = np.exp(t)
data2 = np.sin(2 * np.pi * t)
fig, ax1 = plt.subplots()
months = [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
]
ax1.set_xlabel('month')
ax1.set_ylabel('rainfall', color='tab:blue')
res1 = ax1.boxplot(
rainfall.reshape(-1,12), positions = np.arange(12)-0.25, widths=0.4,
patch_artist=True,
)
for element in ['boxes', 'whiskers', 'fliers', 'means', 'medians', 'caps']:
plt.setp(res1[element], color='k')
for patch in res1['boxes']:
patch.set_facecolor('tab:blue')
ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
ax2.set_ylabel('floods', color='tab:orange')
res2 = ax2.boxplot(
floods.reshape(-1,12), positions = np.arange(12)+0.25, widths=0.4,
patch_artist=True,
)
##from
for element in ['boxes', 'whiskers', 'fliers', 'means', 'medians', 'caps']:
plt.setp(res2[element], color='k')
for patch in res2['boxes']:
patch.set_facecolor('tab:orange')
ax1.set_xlim([-0.55, 11.55])
ax1.set_xticks(np.arange(12))
ax1.set_xticklabels(months)
fig.tight_layout() # otherwise the right y-label is slightly clipped
plt.show()
结果看起来像这样:
我认为稍作微调,这实际上看起来相当不错。
我正在尝试绘制 18 年月降雨量和洪水频率记录的箱线图。即每个 x 刻度是月份,每个 x 刻度与两个箱线图相关联,一个是降雨量,一个是洪水频率。到目前为止,我已经设法使用 seaborn 绘制了这些图(请参见以下代码和图像),但是我不知道如何创建具有两个 y 轴的箱线图,我需要它,因为每个变量的比例不同。
数据如下(数据集中flood_freq的最大值为7,此处未显示):
Group Rainfall Flood_freq
0 Jan 115.679997 0
1 Jan 72.929999 0
2 Jan 39.719999 0
3 Jan 46.799999 1
4 Jan 54.989998 0
...
212 Dec 51.599998 0
213 Dec 45.359999 0
214 Dec 10.260000 0
215 Dec 52.709998 0
这是我用过的代码:
dd=pd.melt(FBPdf,id_vars=['Group'],value_vars=['Rainfall','Flood_freq'],var_name='Data')
sns.boxplot(x='Group',y='value',data=dd,hue='Data')
结果是:
从那以后我查看了 seaborn 文档,它似乎不允许 2 个 y 轴 (
非常感谢您!
借助一些虚假数据和 this tutorial and this answer 的一点帮助,这里有一个简单的示例,说明如何仅使用 numpy
和 matplotlib
:
from matplotlib import pyplot as plt
import numpy as np
rainfall = np.random.rand((12*18))*300
floods = np.random.rand((12*18))*2
t = np.arange(0.01, 10.0, 0.01)
data1 = np.exp(t)
data2 = np.sin(2 * np.pi * t)
fig, ax1 = plt.subplots()
months = [
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',
]
ax1.set_xlabel('month')
ax1.set_ylabel('rainfall', color='tab:blue')
res1 = ax1.boxplot(
rainfall.reshape(-1,12), positions = np.arange(12)-0.25, widths=0.4,
patch_artist=True,
)
for element in ['boxes', 'whiskers', 'fliers', 'means', 'medians', 'caps']:
plt.setp(res1[element], color='k')
for patch in res1['boxes']:
patch.set_facecolor('tab:blue')
ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
ax2.set_ylabel('floods', color='tab:orange')
res2 = ax2.boxplot(
floods.reshape(-1,12), positions = np.arange(12)+0.25, widths=0.4,
patch_artist=True,
)
##from
for element in ['boxes', 'whiskers', 'fliers', 'means', 'medians', 'caps']:
plt.setp(res2[element], color='k')
for patch in res2['boxes']:
patch.set_facecolor('tab:orange')
ax1.set_xlim([-0.55, 11.55])
ax1.set_xticks(np.arange(12))
ax1.set_xticklabels(months)
fig.tight_layout() # otherwise the right y-label is slightly clipped
plt.show()
结果看起来像这样:
我认为稍作微调,这实际上看起来相当不错。