簡體   English   中英

如何在 matplotlib 中制作帶注釋的分組堆疊條形圖?

[英]How to make annotated grouped stacked barchart in matplotlib?

我有從 covid19 跟蹤站點上抓取的 covid19 跟蹤時間序列數據。 我想制作一個帶注釋的分組堆疊條形圖。 為此,我使用matplotlibseaborn制作 plot,我想出了繪制數據以呈現相應的條形圖。 我在SO中嘗試了 plot 注釋,但沒有得到正確的注釋 plot。另外,我在為時間序列數據獲取分組堆疊條形圖時遇到了一些問題。 任何人都可以建議這樣做的可能方法嗎? 任何的想法?

我的嘗試

這是我從covid19跟蹤網站上抓取的可重現時間序列數據

import pandas as pd
from datetime import date
import matplotlib.pyplot as plt
import seaborn as sns

bigdf = pd.read_csv("coviddf.csv")
bigdf['run_date'] = pd.to_datetime(bigdf['run_date'])

for g, d in bigdf.groupby(['company']):
    data = d.groupby(['run_date','county-state', 'company', 'est'], as_index=True).agg({'new': sum, 'confirmed': sum, 'death': sum}).stack().reset_index().rename(columns={'level_4': 'type', 0: 'val'})
    print(f'{g}')
    g = sns.FacetGrid(data, col='est', sharex=False, sharey=False, height=5, col_wrap=4)
    g.map(sns.barplot, 'run_date', 'val', 'type', order=data.run_date.dt.date.unique(), hue_order=data['type'].unique())
    g.add_legend()
    g.set_xticklabels(rotation=90)
    g.set(yscale='log')
    plt.tight_layout()
    plt.show()

我從上面的嘗試中遇到了幾個問題。 我需要制作分組堆疊條形圖,其中每個組都是不同的公司,每個堆疊條形圖都是單獨的機構(也就是coviddf.csvest列),所以每個公司可能有多個機構,所以我想看看新的數量, 確診和死亡 covid19 病例在分組堆疊條形圖中。 有沒有辦法為這個時間序列制作帶注釋的分組堆疊條形圖? 任何人都可以提出實現這一目標的可能方法嗎? 如何在一頁中制作這些圖? 任何的想法?

希望 output

我試着像這篇文章第二篇相關文章那樣制作分組堆疊條形圖。 這是我想要制作的所需帶注釋的分組堆疊條形圖:

在此處輸入圖像描述

誰能指出我如何從當前的嘗試中實現這一點? 對此有什么想法嗎?

分組酒吧 Plot

  • 這不完全是您所要求的,但我認為這是一個更好的選擇。
    • 這當然是一個更容易的選擇。
    • 堆疊條的問題是confirmed與其他值相比太大,您將無法看到newdeath
  • 我認為此數據的最佳選擇是水平條 plot,每個companyest都有一個組。
import pandas as pd

# load the data
df = pd.read_csv("https://gist.githubusercontent.com/jerry-shad/318595505684ea4248a6cc0949788d33/raw/31bbeb08f329b4b96605b8f2a48f6c74c3e0b594/coviddf.csv")
df.drop(columns=['Unnamed: 0'], inplace=True)  # drop this extra column

# select columns and shape the dataframe
dfs = df.iloc[:, [2, 3, 4, 12, 13]].set_index(['company', 'est']).sort_index(level=0)

# display(dfs)
                      confirmed  new  death
company        est                         
Agri  Co.      235        10853    0    237
CS  Packers    630        10930   77    118
Caviness       675          790    5     19
Central Valley 6063A       6021   44     72
FPL            332         5853   80    117

# plot
ax = dfs.plot.barh(figsize=(8, 25), width=0.8)
plt.xscale('log')
plt.grid(True)
plt.tick_params(labelbottom=True, labeltop=True)
plt.xlim(10**0, 1000000)

# annotate the bars
for rect in ax.patches:
    # Find where everything is located
    height = rect.get_height()
    width = rect.get_width()
    x = rect.get_x()
    y = rect.get_y()

    # The width of the bar is the count value and can used as the label
    label_text = f'{width:.0f}'

    label_x = x + width
    label_y = y + height / 2

    # don't include label if it's equivalently 0
    if width > 0.001:
        ax.annotate(label_text, xy=(label_x, label_y), va='center', xytext=(2, -1), textcoords='offset points')

在此處輸入圖像描述

堆積條 Plot

  • newdeathconfirmed相比幾乎看不出來。
dfs.plot.barh(stacked=True, figsize=(8, 15))
plt.xscale('log')

在此處輸入圖像描述

我在 matplotlib 和后來的 Plotly 中找不到有關如何創建 GROUPED 和 STACKED 條形圖的信息時遇到了麻煩。

這是我嘗試解決您的問題(使用 Plotly):

# Import packages
import pandas as pd
from datetime import date
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

# Load data (I used the raw GitHub link so that no local file download was required)
bigdf = pd.read_csv("https://gist.githubusercontent.com/jerry-shad/318595505684ea4248a6cc0949788d33/raw/31bbeb08f329b4b96605b8f2a48f6c74c3e0b594/coviddf.csv")

# Get all companies names and number of companies
allComp = np.unique(bigdf.company)
numComp = allCompanies.shape[0]

# For all the companies
for i in range(numComp):
    # Grab company data and the names of the establishments for that company
    comp = allComp[i]
    compData = bigdf.loc[bigdf.company == comp]
    estabs = compData.est.to_numpy().astype(str)
    numEst = compData.shape[0]

    # Grab the new, confirmed, and death values for each of the establishments in that company
    newVals = []
    confirmedVals = []
    deathVals = []
    for i in range(numEst):
        estabData = compData.loc[compData.est == estabs[i]]
        newVals.append(estabData.new.to_numpy()[0])
        confirmedVals.append(estabData.confirmed.to_numpy()[0])
        deathVals.append(estabData.death.to_numpy()[0])

    # Load that data into a Plotly graph object
    fig = go.Figure(
        data=[
            go.Bar(name='New', x=estabs, y=newVals, yaxis='y', offsetgroup=1),
            go.Bar(name='Confirmed', x=estabs, y=confirmedVals, yaxis='y', offsetgroup=2),
            go.Bar(name='Death', x=estabs, y=deathVals, yaxis='y', offsetgroup=3)
        ]
    )

    # Update the layout (add time, set x/y axis titles, and bar graph mode)
    fig.update_layout(title='COVID Data for ' + comp, xaxis=dict(type='category'), xaxis_title='Establishment', 
                      yaxis_title='Value', barmode='stack')
    fig.show()

其中output 是每個公司的 16 個單獨的 Plotly 圖表(它們是可交互的,您可以打開各種軌跡,因為新/確認/死亡值的縮放並不那么容易)。 每個 plot 在 x 軸上都有該公司的所有機構,每個機構的新/確認/死亡值作為堆疊條形圖。

這是一個示例 plot: HBS 公司 COVID 數據

我知道這並不能完全回答你的問題,但我希望你欣賞我的努力:)

暫無
暫無

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

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