[英]How to make annotated grouped stacked barchart in matplotlib?
我有從 covid19 跟蹤站點上抓取的 covid19 跟蹤時間序列數據。 我想制作一個帶注釋的分組堆疊條形圖。 為此,我使用matplotlib
和seaborn
制作 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.csv
中est
列),所以每個公司可能有多個機構,所以我想看看新的數量, 確診和死亡 covid19 病例在分組堆疊條形圖中。 有沒有辦法為這個時間序列制作帶注釋的分組堆疊條形圖? 任何人都可以提出實現這一目標的可能方法嗎? 如何在一頁中制作這些圖? 任何的想法?
希望 output
我試着像這篇文章和第二篇相關文章那樣制作分組堆疊條形圖。 這是我想要制作的所需帶注釋的分組堆疊條形圖:
誰能指出我如何從當前的嘗試中實現這一點? 對此有什么想法嗎?
confirmed
與其他值相比太大,您將無法看到new
和death
company
和est
都有一個組。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')
new
和death
與confirmed
相比幾乎看不出來。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 軸上都有該公司的所有機構,每個機構的新/確認/死亡值作為堆疊條形圖。
我知道這並不能完全回答你的問題,但我希望你欣賞我的努力:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.