我正在使用 pandas.plot
创建分组条形图。我想用每个数据点的两个不同标记覆盖该图表。 IRL 标记代表来自先前时间段的相同数据。我知道如何使用 kind='line'
和 linestyle='None'
创建标记,但我不知道如何让它们与条形对齐。所需的输出将为每个数据点(来自下面 MRE 中的 df
)提供一个彩色条,并且与该条对齐的是两个可区分的标记,分别代表 df2
和 df3
。
我想创建另一个仅使用标记的条形图,但 AFAIK 是不可能的。我还陷入了使用 yerr
的兔子洞,如本例所示:
How can I add markers on a bar graph in python?
但似乎不可能为上/下误差生成两个单独的标记,这在此处是必要的。
这是我想要实现的一个简单示例,唯一的问题是标记的 x 对齐。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
df_data = {'A':np.random.randint(20, 50, 5),
'B':np.random.randint(10, 50, 5),
'C':np.random.randint(30, 50, 5),
'D':np.random.randint(30, 100, 5)}
df2_data = {'A':np.random.randint(20, 50, 5),
'B':np.random.randint(10, 50, 5),
'C':np.random.randint(30, 50, 5),
'D':np.random.randint(30, 100, 5)}
df3_data = {'A':np.random.randint(20, 50, 5),
'B':np.random.randint(10, 50, 5),
'C':np.random.randint(30, 50, 5),
'D':np.random.randint(30, 100, 5)}
df = pd.DataFrame(data=df_data)
df2 = pd.DataFrame(data=df2_data)
df3 = pd.DataFrame(data=df3_data)
fig = plt.figure()
bar_colors = ['red', 'blue', 'green', 'goldenrod']
ax = fig.gca()
df2.plot(kind='line', ax=ax, linestyle='None', marker='^',
color=bar_colors,
markerfacecolor='white', legend=False)
df3.plot(kind='line', ax=ax, linestyle='None', marker='o',
color=bar_colors,
markerfacecolor='white', legend=False)
df.plot(kind='bar', ax=ax, color=bar_colors, width=0.8, rot=0)
plt.show()
答案 0 :(得分:1)
使用 seaborn 的 pointplot
,您可以使用 dodge=
来展开标记,类似于条形。但是,对 pointplot
和 barplot
使用的闪避宽度的解释是不同的。此宽度可以按照 this github issue 中的注释进行调整。
似乎还没有选项可以将面部颜色与标记边缘颜色分开调整。但它们可以在之后更改。此外,图例将包含所有元素,并且可以更改为仅包含最后 4 个。
由于 seaborn 更喜欢 "long form" 中的数据帧,因此需要使用 melt
。以及为原始索引创建显式列。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
df_data = {'A': np.random.randint(20, 50, 5),
'B': np.random.randint(10, 50, 5),
'C': np.random.randint(30, 50, 5),
'D': np.random.randint(30, 100, 5)}
df2_data = {'A': np.random.randint(20, 50, 5),
'B': np.random.randint(10, 50, 5),
'C': np.random.randint(30, 50, 5),
'D': np.random.randint(30, 100, 5)}
df3_data = {'A': np.random.randint(20, 50, 5),
'B': np.random.randint(10, 50, 5),
'C': np.random.randint(30, 50, 5),
'D': np.random.randint(30, 100, 5)}
df = pd.DataFrame(data=df_data)
df2 = pd.DataFrame(data=df2_data)
df3 = pd.DataFrame(data=df3_data)
bar_colors = ['red', 'blue', 'green', 'goldenrod']
dogde_width = .8 - .8 / len(bar_colors)
ax = sns.pointplot(data=df2.melt(ignore_index=False).reset_index(),
x='index', y='value', hue='variable', linestyles='', markers='^',
palette=bar_colors, dodge=dogde_width)
sns.pointplot(data=df3.melt(ignore_index=False).reset_index(),
x='index', y='value', hue='variable', linestyles='', markers='o',
palette=bar_colors, dodge=dogde_width, ax=ax)
sns.barplot(data=df.melt(ignore_index=False).reset_index(),
x='index', y='value', hue='variable',
palette=bar_colors, dodge=True, ax=ax)
handles, labels = ax.get_legend_handles_labels()
leg_num = len(bar_colors)
ax.legend(handles[-leg_num:], labels[-leg_num:]) # use only four last elements for the legend
for markers in ax.collections:
markers.set_facecolor('white')
markers.set_linewidth(1)
plt.show()
答案 1 :(得分:1)
使用 matplotlibs bar() 和 scatter() 我想出了这个解决方案:
#Exchange 2010 Script
$fwds = get-mailbox | Where-Object { $_.ForwardingAddress -ne $null } | select Name, ForwardingAddress, DeliverToMailboxAndForward
foreach ($fwd in $fwds)
{
$ErrorActionPreference = "SilentlyContinue"
$fwd | add-member -membertype noteproperty -name "ContactAddress" -value (get-contact $fwd.ForwardingAddress).WindowsEmailAddress
$ErrorActionPreference = "Continue"
#Maakt objecten aan die in C# uit te lezen zijn
if($fwd.ContactAddress)
{
$properties = @{
Name = $fwd.Name
ContactAddress = $fwd.ContactAddress
DeliverToMailboxAndForward = $fwd.DeliverToMailboxAndForward
}
$o = New-Object psobject -Property $properties;
# Dit zet het object bruikbaar als object in c#
Write-Output $o
}
}
这应该是这样的:
您可以尝试不同的标记和颜色。