Python pandas 如果 twinx 两个 y 轴,则绘制平移 x 轴
Python pandas plotting shift x-axis if twinx two y-axes
我有一个包含 3 列的数据框:其中一列是 "groupby" 列,另外两列是带值的 "normal" 列。我也想生成箱线图和条形图。在条形图上,我想可视化每个组元素的出现次数。让我的示例代码更详细地告诉这个数据框:
li_str = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten']
df = pd.DataFrame([[i]+j[k] for i,j in {li_str[i]:np.random.randn(j, 2).tolist() for i,j in \
enumerate(np.random.randint(5, 15, len(li_str)))}.items() for k in range(len(j))]
, columns=['A', 'B', 'C'])
所以上面我为 li_str
中的每个元素生成随机数的随机值,我为列 B
和 C
.
执行此操作
然后我只可视化一个箱线图:
fig, ax = plt.subplots(figsize=(16,6))
p1 = df.boxplot(ax=ax, column='B', by='A', sym='')
我的结果是:
现在我可视化每个组的元素数量(因此我在上面使用 np.random.randint(5, 15, len(li_str))
代码生成的随机数):
fig, ax = plt.subplots(figsize=(16,6))
df_gb = df.groupby('A').count()
p2 = df_gb['B'].plot(ax=ax, kind='bar', figsize=(16,6), colormap='Set2', alpha=0.3)
plt.ylim([0, 20])
我的结果是:
现在我想将这两个合二为一:
fig, ax = plt.subplots(figsize=(16,6))
ax2 = ax.twinx()
df_gb = df.groupby('A').count()
p1 = df.boxplot(ax=ax, column='B', by='A', sym='')
p2 = df_gb['B'].plot(ax=ax2, kind='bar', figsize=(16,6)
, colormap='Set2', alpha=0.3, secondary_y=True)
plt.ylim([0, 20])
我的结果是:
有人知道为什么我的箱线图向右移动了一个 x 轴刻度吗?我使用 Python 3.5.1,pandas 0.17.0,matplotlib 1.4.3
谢谢!!!
这是因为即使标签相同,箱线图和条形图也不使用相同的 xticks。
df.boxplot(column='B', by='A')
plt.xticks()
(array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), <a list of 10 Text xticklabel objects>)
df.groupby('A').count()['B'].plot(kind='bar')
plt.xticks()
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), <a list of 10 Text xticklabel objects>)
在我看来,这似乎是一个不一致的地方,应该在 matplotlib 中修复 boxplot()
,但我可能只是忽略了基本原理。
作为解决方法,使用 matplotlib bar()
,它允许您指定 xticks 以匹配箱线图的 xticks(我没有找到使用 df.plot(kind='bar')
.[=16= 的方法) ]
df.boxplot(column='B', by='A')
plt.twinx()
plt.bar(left=plt.xticks()[0], height=df.groupby('A').count()['B'],
align='center', alpha=0.3)
我有一个包含 3 列的数据框:其中一列是 "groupby" 列,另外两列是带值的 "normal" 列。我也想生成箱线图和条形图。在条形图上,我想可视化每个组元素的出现次数。让我的示例代码更详细地告诉这个数据框:
li_str = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten']
df = pd.DataFrame([[i]+j[k] for i,j in {li_str[i]:np.random.randn(j, 2).tolist() for i,j in \
enumerate(np.random.randint(5, 15, len(li_str)))}.items() for k in range(len(j))]
, columns=['A', 'B', 'C'])
所以上面我为 li_str
中的每个元素生成随机数的随机值,我为列 B
和 C
.
然后我只可视化一个箱线图:
fig, ax = plt.subplots(figsize=(16,6))
p1 = df.boxplot(ax=ax, column='B', by='A', sym='')
我的结果是:
现在我可视化每个组的元素数量(因此我在上面使用 np.random.randint(5, 15, len(li_str))
代码生成的随机数):
fig, ax = plt.subplots(figsize=(16,6))
df_gb = df.groupby('A').count()
p2 = df_gb['B'].plot(ax=ax, kind='bar', figsize=(16,6), colormap='Set2', alpha=0.3)
plt.ylim([0, 20])
我的结果是:
现在我想将这两个合二为一:
fig, ax = plt.subplots(figsize=(16,6))
ax2 = ax.twinx()
df_gb = df.groupby('A').count()
p1 = df.boxplot(ax=ax, column='B', by='A', sym='')
p2 = df_gb['B'].plot(ax=ax2, kind='bar', figsize=(16,6)
, colormap='Set2', alpha=0.3, secondary_y=True)
plt.ylim([0, 20])
我的结果是:
有人知道为什么我的箱线图向右移动了一个 x 轴刻度吗?我使用 Python 3.5.1,pandas 0.17.0,matplotlib 1.4.3
谢谢!!!
这是因为即使标签相同,箱线图和条形图也不使用相同的 xticks。
df.boxplot(column='B', by='A')
plt.xticks()
(array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), <a list of 10 Text xticklabel objects>)
df.groupby('A').count()['B'].plot(kind='bar')
plt.xticks()
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), <a list of 10 Text xticklabel objects>)
在我看来,这似乎是一个不一致的地方,应该在 matplotlib 中修复 boxplot()
,但我可能只是忽略了基本原理。
作为解决方法,使用 matplotlib bar()
,它允许您指定 xticks 以匹配箱线图的 xticks(我没有找到使用 df.plot(kind='bar')
.[=16= 的方法) ]
df.boxplot(column='B', by='A')
plt.twinx()
plt.bar(left=plt.xticks()[0], height=df.groupby('A').count()['B'],
align='center', alpha=0.3)