簡體   English   中英

具有多個標記的分組條形圖

[英]Grouped bar chart with multiple markers

我正在使用pandas.plot創建分組條形圖。 我想用每個數據點兩個不同的標記覆蓋該圖表。 IRL 標記代表之前時間段的相同數據。 我知道如何使用kind='line'linestyle='None'創建標記,但我不知道如何讓它們與條對齊。 所需的 output 將為每個數據點(來自下面的 MRE 中的df )有一個彩色條,並且與該條對齊的是兩個可區分的標記,分別代表df2df3

我想創建另一個只使用標記的條形圖,但 AFAIK 是不可能的。 在這個例子中,我也陷入了使用yerr的兔子洞: 如何在 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()

使用pointplot的點圖,您可以使用dodge=來散布標記,類似於條形圖。 但是,對於pointplotbarplot使用的閃避寬度的解釋是不同的。 此寬度可以按照此 github 問題中的注釋進行調整。

似乎還沒有選項可以將面部顏色與標記邊緣顏色分開。 但之后可以更改它們。 此外,圖例將包括所有元素,並且可以更改為僅包含最后 4 個元素。

由於 seaborn 更喜歡“長格式”的數據幀,因此需要使用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()

seaborn 條形圖與點圖相結合

使用 matplotlibs bar() 和 scatter() 我想出了這個解決方案:

x = np.arange(len(df))
width = 0.2

fig, ax = plt.subplots()
# main dataframe
ax.bar(x - width *1.5,np.array(df["A"]),width,label="A")
ax.bar(x - width/2 ,np.array(df["B"]),width,label="B")
ax.bar(x + width/2 ,np.array(df["C"]),width,label="C")
ax.bar(x + width *1.5 ,np.array(df["D"]),width,label="D")

ax.set_xticks(x)
ax.legend()

# df2
ax.scatter(x - width *1.5,np.array(df2["A"]),c="black",marker="_",zorder=2)
ax.scatter(x - width/2,np.array(df2["B"]),c="black",marker="_",zorder=2)
ax.scatter(x + width/2,np.array(df2["C"]),c="black",marker="_",zorder=2)
ax.scatter(x + width *1.5,np.array(df2["D"]),c="black",marker="_",zorder=2)

# df3
ax.scatter(x - width *1.5,np.array(df3["A"]),c="black",marker="_",zorder=2)
ax.scatter(x - width/2,np.array(df3["B"]),c="black",marker="_",zorder=2)
ax.scatter(x + width/2,np.array(df3["C"]),c="black",marker="_",zorder=2)
ax.scatter(x + width *1.5,np.array(df3["D"]),c="black",marker="_",zorder=2)

這應該是這樣的:

在此處輸入圖像描述

您可以嘗試不同的標記和 colors。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM