Pandas箱线图的第二个轴

huangapple go评论61阅读模式
英文:

Second axis for Pandas boxplots

问题

我有一个类似这样的并列箱线图

second_axis = {0: 'a', 1: 'b', 2: 'c'}

import pandas as pd
import numpy as np
group = np.array([np.random.binomial(2, 0.4) for _ in range(100)])
data = [np.random.uniform(0, 5) for _ in range(len(group))]
df = pd.DataFrame({'data': data, 'group': group})
df.boxplot(by='group', vert=False)


我尝试在图上添加第二个垂直轴,我的期望输出是这样的:

[![在这里输入图片描述][1]][1]

我想知道是否有办法在pandas/matplotlib中实现这个效果。

  [1]: https://i.stack.imgur.com/XEpbX.png
英文:

I have a side-by-side boxplot like this

second_axis = {0:'a',1: 'b', 2: 'c'}

import pandas as pd
import numpy as np
group = np.array([  np.random.binomial(2,0.4)   for _ in range(100)])
data = [  np.random.uniform(0,5)   for _ in range(len(group))]
df = pd.DataFrame({'data': data, 'group': group} )
df.boxplot(by='group', vert=False)

I am trying to add the 2nd vertical axis to the plot, my desired output is something like this:

Pandas箱线图的第二个轴

I wonder whether there is a way to do this with pandas/matplotlib

答案1

得分: 2

你可以使用恒等变换创建一个 secondary_yaxis(不要与创建新的独立 y 轴的 twinx() 混淆,后者要复杂得多)。请注意,内部的箱线图是从 1 开始编号的。

from matplotlib import pyplot as plt
import pandas as pd
import numpy as np

group = np.array([np.random.binomial(2, 0.4) for _ in range(100)])
data = [np.random.uniform(0, 5) for _ in range(len(group))]
df = pd.DataFrame({'data': data, 'group': group})
ax = df.boxplot(by='group', vert=False)
sec_ax = ax.secondary_yaxis('right')
second_axis = {0: 'a', 1: 'b', 2: 'c'}
sec_ax.set_yticks(range(1, 1 + len(second_axis)), second_axis.values())
plt.tight_layout()
plt.show()

Pandas箱线图的第二个轴

PS: 如果组是非连续的数字,你可以使用:

sec_ax.set_yticks(ax.get_yticks(), [second_axis[int(label.get_text())] for label in ax.get_yticklabels()])

或者当它们是字符串时:

sec_ax.set_yticks(ax.get_yticks(), [second_axis[label.get_text()] for label in ax.get_yticklabels()])
英文:

You can create a secondary_yaxis with the identity transformation (not to be confused with twinx() which creates a new independent y-axis and is much trickier). Note that internally, the boxplots are numbered starting from 1.

from matplotlib import pyplot as plt
import pandas as pd
import numpy as np

group = np.array([np.random.binomial(2, 0.4) for _ in range(100)])
data = [np.random.uniform(0, 5) for _ in range(len(group))]
df = pd.DataFrame({'data': data, 'group': group})
ax = df.boxplot(by='group', vert=False)
sec_ax = ax.secondary_yaxis('right')
second_axis = {0: 'a', 1: 'b', 2: 'c'}
sec_ax.set_yticks(range(1, 1 + len(second_axis)), second_axis.values())
plt.tight_layout()
plt.show()

Pandas箱线图的第二个轴

PS: If the groups are non-successive numbers, you can use:

sec_ax.set_yticks(ax.get_yticks(), [second_axis[int(label.get_text())] for label in ax.get_yticklabels()])

or when they are strings:

sec_ax.set_yticks(ax.get_yticks(), [second_axis[label.get_text()] for label in ax.get_yticklabels()])

huangapple
  • 本文由 发表于 2023年3月10日 00:05:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75687157.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定