如何绘制 plotBox 和不同轴的线图
How to plot plotBox and a line plot with different axes
我有一个可以用这种方式制作的数据集:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
date_range = pd.date_range(start='2021-11-20', end='2022-01-09').to_list()
df_left = pd.DataFrame(columns=['Date','Values'])
for d in date_range*3:
if (np.random.randint(0,2) == 0):
df_left = df_left.append({'Date': d, 'Values': np.random.randint(1,11)}, ignore_index=True)
df_left["year-week"] = df_left["Date"].dt.strftime("%Y-%U")
df_right = pd.DataFrame(
{
"Date": date_range,
"Values": np.random.randint(0, 50 , len(date_range)),
}
)
df_right_counted = df_right.resample('W', on='Date')['Values'].sum().to_frame().reset_index()
df_right_counted["year-week"] = df_right_counted["Date"].dt.strftime("%Y-%U")
pd_right_counted:
Date Values year-week
0 2021-12-05 135 2021-49
1 2021-12-12 219 2021-50
2 2021-12-19 136 2021-51
3 2021-12-26 158 2021-52
4 2022-01-02 123 2022-01
5 2022-01-09 222 2022-02
和pd_left:
Date Values year-week
0 2021-12-01 10 2021-48
1 2021-12-05 1 2021-49
2 2021-12-07 5 2021-49
...
13 2022-01-07 7 2022-01
14 2022-01-08 9 2022-01
15 2022-01-09 6 2022-02
我想在 matplotlib 中创建这个图表。
箱线图是用 df_left
绘制的,它使用左侧的 y 轴 ,法线图是用 df_right_counted
绘制的,使用右侧的 y 轴。
到目前为止,这是我的尝试(+ 来自 的修复),但我完全坚持:
- 从同一周开始制作这两个图表(我想从 2021-49 开始)
- 在右侧绘制另一个 x 轴,让线图使用它
这是我目前的尝试:
fig, ax = plt.subplots(nrows=1, ncols=1, dpi=100)
fig.tight_layout()
fig.set_tight_layout(True)
fig.set_facecolor('white')
ax2=ax.twinx()
df_left.boxplot(figsize=(31, 8), column='Values', by='year-week', ax=ax)
df_right_counted.plot(figsize=(31, 8), x='year-week', y='Values', ax=ax2)
plt.show()
你能给我一些指导吗?我还在学习使用 matplotlib
其中一个问题是 resample('W', on='Date')
和 .dt.strftime("%Y-%U")
似乎导致两个数据帧中的数字不同。另一个问题是 boxplot 在内部标记以 1 开头的框。
一些可能的解决方法:
- 强制
boxplot
从一开始的数字
- 通过先提取
year-week
然后使用 group_by
创建计数;这样周数应该是一致的
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
date_range = pd.date_range(start='2021-11-20', end='2022-01-09').to_list()
df_left = pd.DataFrame(columns=['Date', 'Values'])
for d in date_range * 3:
if (np.random.randint(0, 2) == 0):
df_left = df_left.append({'Date': d, 'Values': np.random.randint(1, 11)}, ignore_index=True)
df_left["year-week"] = df_left["Date"].dt.strftime("%Y-%U")
df_right = pd.DataFrame({"Date": date_range,
"Values": np.random.randint(0, 50, len(date_range))})
df_right["year-week"] = df_right["Date"].dt.strftime("%Y-%U")
df_right_counted = df_right.groupby('year-week')['Values'].sum().to_frame().reset_index()
fig, ax = plt.subplots(nrows=1, ncols=1, dpi=100)
fig.tight_layout()
fig.set_tight_layout(True)
fig.set_facecolor('white')
ax2 = ax.twinx()
df_left.boxplot(figsize=(31, 8), column='Values', by='year-week', ax=ax,
positions=np.arange(len(df_left['year-week'].unique())))
df_right_counted.plot(figsize=(31, 8), x='year-week', y='Values', ax=ax2)
plt.show()
我有一个可以用这种方式制作的数据集:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
date_range = pd.date_range(start='2021-11-20', end='2022-01-09').to_list()
df_left = pd.DataFrame(columns=['Date','Values'])
for d in date_range*3:
if (np.random.randint(0,2) == 0):
df_left = df_left.append({'Date': d, 'Values': np.random.randint(1,11)}, ignore_index=True)
df_left["year-week"] = df_left["Date"].dt.strftime("%Y-%U")
df_right = pd.DataFrame(
{
"Date": date_range,
"Values": np.random.randint(0, 50 , len(date_range)),
}
)
df_right_counted = df_right.resample('W', on='Date')['Values'].sum().to_frame().reset_index()
df_right_counted["year-week"] = df_right_counted["Date"].dt.strftime("%Y-%U")
pd_right_counted:
Date Values year-week
0 2021-12-05 135 2021-49
1 2021-12-12 219 2021-50
2 2021-12-19 136 2021-51
3 2021-12-26 158 2021-52
4 2022-01-02 123 2022-01
5 2022-01-09 222 2022-02
和pd_left:
Date Values year-week
0 2021-12-01 10 2021-48
1 2021-12-05 1 2021-49
2 2021-12-07 5 2021-49
...
13 2022-01-07 7 2022-01
14 2022-01-08 9 2022-01
15 2022-01-09 6 2022-02
我想在 matplotlib 中创建这个图表。
箱线图是用 df_left
绘制的,它使用左侧的 y 轴 ,法线图是用 df_right_counted
绘制的,使用右侧的 y 轴。
到目前为止,这是我的尝试(+ 来自
- 从同一周开始制作这两个图表(我想从 2021-49 开始)
- 在右侧绘制另一个 x 轴,让线图使用它
这是我目前的尝试:
fig, ax = plt.subplots(nrows=1, ncols=1, dpi=100)
fig.tight_layout()
fig.set_tight_layout(True)
fig.set_facecolor('white')
ax2=ax.twinx()
df_left.boxplot(figsize=(31, 8), column='Values', by='year-week', ax=ax)
df_right_counted.plot(figsize=(31, 8), x='year-week', y='Values', ax=ax2)
plt.show()
其中一个问题是 resample('W', on='Date')
和 .dt.strftime("%Y-%U")
似乎导致两个数据帧中的数字不同。另一个问题是 boxplot 在内部标记以 1 开头的框。
一些可能的解决方法:
- 强制
boxplot
从一开始的数字 - 通过先提取
year-week
然后使用group_by
创建计数;这样周数应该是一致的
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
date_range = pd.date_range(start='2021-11-20', end='2022-01-09').to_list()
df_left = pd.DataFrame(columns=['Date', 'Values'])
for d in date_range * 3:
if (np.random.randint(0, 2) == 0):
df_left = df_left.append({'Date': d, 'Values': np.random.randint(1, 11)}, ignore_index=True)
df_left["year-week"] = df_left["Date"].dt.strftime("%Y-%U")
df_right = pd.DataFrame({"Date": date_range,
"Values": np.random.randint(0, 50, len(date_range))})
df_right["year-week"] = df_right["Date"].dt.strftime("%Y-%U")
df_right_counted = df_right.groupby('year-week')['Values'].sum().to_frame().reset_index()
fig, ax = plt.subplots(nrows=1, ncols=1, dpi=100)
fig.tight_layout()
fig.set_tight_layout(True)
fig.set_facecolor('white')
ax2 = ax.twinx()
df_left.boxplot(figsize=(31, 8), column='Values', by='year-week', ax=ax,
positions=np.arange(len(df_left['year-week'].unique())))
df_right_counted.plot(figsize=(31, 8), x='year-week', y='Values', ax=ax2)
plt.show()