gpt4 book ai didi

python - 如何在 matplotlib 图中添加轴偏移?

转载 作者:太空狗 更新时间:2023-10-30 00:01:14 28 4
gpt4 key购买 nike

我在同一张图上绘制了 seaborn 中的多个点图。 x 轴是有序的,而不是数字;每个点图的序数值相同。我想将每个图稍微移到一边,就像 pointplot(dodge=...) 参数在单个图中的多行内所做的那样,但在这种情况下,多个不同的图相互叠加。我该怎么做?

理想情况下,我想要一种适用于任何 matplotlib 绘图的技术,而不仅仅是 seaborn。向数据添加偏移量并不容易,因为数据不是数字。

显示绘图重叠并使它们难以阅读的示例(在每个绘图中闪避都可以)

import pandas as pd
import seaborn as sns

df1 = pd.DataFrame({'x':list('ffffssss'), 'y':[1,2,3,4,5,6,7,8], 'h':list('abababab')})
df2 = df1.copy()
df2['y'] = df2['y']+0.5
sns.pointplot(data=df1, x='x', y='y', hue='h', ci='sd', errwidth=2, capsize=0.05, dodge=0.1, markers='<')
sns.pointplot(data=df2, x='x', y='y', hue='h', ci='sd', errwidth=2, capsize=0.05, dodge=0.1, markers='>')

Result

我可以使用 seaborn 以外的东西,但自动置信度/错误栏非常方便,所以我宁愿在这里坚持使用 seaborn。

最佳答案

首先针对最一般的情况回答这个问题。可以通过将图中的艺术家移动一定量来实现闪避。使用点作为该类次的单位可能很有用。例如。您可能希望将绘图上的标记移动 5 个点。
这种转变可以通过向艺术家的数据转换添加翻译来实现。在这里,我提出了一个 ScaledTranslation

现在为了保持这个最一般化,可以编写一个函数,将绘图方法、轴和数据作为输入,另外还要应用一些闪避,例如

draw_dodge(ax.errorbar, X, y, yerr =y/4., ax=ax, dodge=d, marker="d" )

完整的功能代码:

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


def draw_dodge(*args, **kwargs):
func = args[0]
dodge = kwargs.pop("dodge", 0)
ax = kwargs.pop("ax", plt.gca())
trans = ax.transData + transforms.ScaledTranslation(dodge/72., 0,
ax.figure.dpi_scale_trans)
artist = func(*args[1:], **kwargs)
def iterate(artist):
if hasattr(artist, '__iter__'):
for obj in artist:
iterate(obj)
else:
artist.set_transform(trans)
iterate(artist)
return artist

X = ["a", "b"]
Y = np.array([[1,2],[2,2],[3,2],[1,4]])

Dodge = np.arange(len(Y),dtype=float)*10
Dodge -= Dodge.mean()

fig, ax = plt.subplots()

for y,d in zip(Y,Dodge):
draw_dodge(ax.errorbar, X, y, yerr =y/4., ax=ax, dodge=d, marker="d" )

ax.margins(x=0.4)
plt.show()

enter image description here

您可以将它与 ax.plotax.scatter 等一起使用。但是不能与任何 seaborn 函数一起使用,因为它们不会返回任何有用的艺术家一起工作。


现在对于所讨论的案例,剩下的问题是以有用的格式获取数据。一种选择如下。

df1 = pd.DataFrame({'x':list('ffffssss'), 
'y':[1,2,3,4,5,6,7,8],
'h':list('abababab')})
df2 = df1.copy()
df2['y'] = df2['y']+0.5

N = len(np.unique(df1["x"].values))*len([df1,df2])
Dodge = np.linspace(-N,N,N)/N*10


fig, ax = plt.subplots()
k = 0
for df in [df1,df2]:
for (n, grp) in df.groupby("h"):
x = grp.groupby("x").mean()
std = grp.groupby("x").std()
draw_dodge(ax.errorbar, x.index, x.values,
yerr =std.values.flatten(), ax=ax,
dodge=Dodge[k], marker="o", label=n)
k+=1

ax.legend()
ax.margins(x=0.4)
plt.show()

enter image description here

关于python - 如何在 matplotlib 图中添加轴偏移?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50195997/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com