在 Jupyter Notebook 上清理并制作可读的条形图
Posted
技术标签:
【中文标题】在 Jupyter Notebook 上清理并制作可读的条形图【英文标题】:Clean and make readable bar graphs on Jupyter Notebook 【发布时间】:2020-02-26 11:44:03 【问题描述】:这可能是小事,但我怎样才能使我的条形图输出可读。显然,我需要删除条形高度上的 +sign 以及 小数,以便我只保留整数。这是我的数据:
# intialise data of lists.
data = 'Hospital_name':['Jootrh Hospital', 'Jootrh Hospital', 'Embu Hospital', 'Embu Hospital','Bungoma Hospital', 'Bungoma Hospital', 'Keru Hospital', 'Keru Hospital'],
'periodname':["18-Jul", "18-Aug", "18-Jul", "18-Aug","18-Jul", "18-Aug", "18-Jul", "18-Aug"], 'normal deliveries':[452, 458, "NAN", 45,498, 466, "NAN", 450],
'caesarian sections':[67.0, 99.0, 13.0, 13.0,60.0, 19.0, 73.0, "NAN"], 'breach delivery':[10.0, "NAN", 13.0, 137.0,100.0, "NAN", "NAN" ,197.0],
'assisted vd':["NAN", "NAN", 1.0, 37.0,1.0, "NAN", 1.0, 37.0]
# Create DataFrame
df = pd.DataFrame(data)
df
这是我的代码,我正在使用 jupyter notebook:
import numpy as np
import matplotlib.pyplot as plt
grouped = df.groupby('Hospital_name')
ncols=1
nrows = int(np.ceil(grouped.ngroups/ncols))
fig, axes = plt.subplots(nrows=nrows, ncols=ncols,figsize=(10,40), constrained_layout=True)
x_offset = 0.02
y_offset = 0.02
for (key, ax) in zip(grouped.groups.keys(), axes.flatten()):
temp = grouped.get_group(key).replace("NAN",0).plot(kind='bar',ax=ax, title=key)
for bar in temp.patches:
b = bar.get_bbox()
val = ":+.2f".format(b.y1 + b.y0)
ax.annotate(val, ((b.x0 + b.x1)/2 + x_offset, b.y1 + y_offset))
ax.legend()
plt.show()
这是我的输出,看起来很乱
有人可以帮助我的输出看起来可读吗?请注意,我确实需要那些条形高度数字,最终结果将保存在可能是 pdf 的文档中。 +号和小数可以去掉
【问题讨论】:
一些想法。您可以使用tick_params (matplotlib.org/3.1.1/api/_as_gen/…) 旋转xticklabels,您可以使用tight_layout (matplotlib.org/3.1.1/api/_as_gen/…) 改进图形的布局,并使用subplots_adjust (matplotlib.org/3.1.1/api/_as_gen/…) 进一步调整子图周围的空间,您可以使图形更宽带 figsize(第一个值宽度,第二个值高度)。 @Patol75 您是否可以复制它的样本。我已经尝试了一些选项,但似乎我错过了一些东西 【参考方案1】:这样的东西对你有用吗?我知道这是很多变化,并且与我的评论并不完全一致,但这就是我发现的方式。我还意识到您可能需要进行一些调整以适应您拥有的所有其他日期。
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
data = 'Name': ['Jootrh Hospital', 'Jootrh Hospital',
'Embu Hospital', 'Embu Hospital',
'Bungoma Hospital', 'Bungoma Hospital',
'Keru Hospital', 'Keru Hospital'],
'Date': ['18-Jul', '18-Aug', '18-Jul', '18-Aug', '18-Jul', '18-Aug',
'18-Jul', '18-Aug'],
'Norm_Del': [452, 458, np.nan, 45, 498, 466, np.nan, 450],
'Caesa_Sec': [67., 99., 13., 13., 60., 19., 73., np.nan],
'Br_Del': [10., np.nan, 13., 137., 100., np.nan, np.nan, 197.],
'Ass_VD': [np.nan, np.nan, 1., 37., 1., np.nan, 1., 37.]
df = pd.DataFrame(data)
df2 = df.pivot_table(
values=['Norm_Del', 'Caesa_Sec', 'Br_Del', 'Ass_VD'],
index=['Name', 'Date'], fill_value=0)
df2.plot.bar(rot=45, figsize=(16, 8),
color=['xkcd:cerulean', 'xkcd:avocado', 'xkcd:silver',
'xkcd:purple'])
i = 0
for unused, rows in df2.iterrows():
print(rows['Norm_Del'])
plt.annotate(rows['Ass_VD'], xy=(i - 0.19, rows['Ass_VD'] + 5), rotation=0,
color='xkcd:cerulean', fontweight='semibold', ha='center')
plt.annotate(rows['Br_Del'], xy=(i - 0.06, rows['Br_Del'] + 5), rotation=0,
color='xkcd:avocado', fontweight='semibold', ha='center')
plt.annotate(rows['Caesa_Sec'], xy=(i + 0.06, rows['Caesa_Sec'] + 5),
rotation=0, color='xkcd:silver', fontweight='semibold',
ha='center')
plt.annotate(rows['Norm_Del'], xy=(i + 0.19, rows['Norm_Del'] + 5),
rotation=0, color='xkcd:purple', fontweight='semibold',
ha='center')
i += 1
plt.savefig('so.png', bbox_inches='tight')
plt.show()
编辑:
from datetime import datetime
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
data = 'Name': ['Jootrh Hospital', 'Jootrh Hospital',
'Embu Hospital', 'Embu Hospital',
'Bungoma Hospital', 'Bungoma Hospital',
'Keru Hospital', 'Keru Hospital'],
'Date': ['18-Jul', '18-Aug', '18-Jul', '18-Aug', '18-Jul', '18-Aug',
'18-Jul', '18-Aug'],
'Norm_Del': [452, 458, np.nan, 45, 498, 466, np.nan, 450],
'Caesa_Sec': [67., 99., 13., 13., 60., 19., 73., np.nan],
'Br_Del': [10., np.nan, 13., 137., 100., np.nan, np.nan, 197.],
'Ass_VD': [np.nan, np.nan, 1., 37., 1., np.nan, 1., 37.]
df = pd.DataFrame(data)
df2 = df.pivot_table(
values=['Norm_Del', 'Caesa_Sec', 'Br_Del', 'Ass_VD'],
index=['Name', 'Date'], fill_value=0)
names = np.unique([x[0] for x in df2.index.values])
dates = sorted(np.unique([x[1] for x in df2.index.values]),
key=lambda day: datetime.strptime(day, '%d-%b'))
values = df2.columns.values
locLab = [-0.19, -0.06, 0.06, 0.19]
colors = ('xkcd:cerulean', 'xkcd:avocado', 'xkcd:silver', 'xkcd:purple')
fig, axs = plt.subplots(nrows=names.shape[0], figsize=(5 * len(dates),
4 * names.shape[0]))
i = 0
for name in names:
df2.loc[name].reindex(dates).plot.bar(
rot=0, ax=axs[i], title=name, color=colors)
j = 0
for date in dates:
k = 0
maxVal = np.amax(df2.loc[name].values)
for value in values:
val = df2.loc[name].loc[date][value]
axs[i].annotate(val, xy=(j + locLab[k], val + maxVal / 100),
color=colors[k], fontweight='semibold',
ha='center')
k += 1
j += 1
i += 1
plt.tight_layout()
plt.savefig('so.png', bbox_inches='tight')
【讨论】:
完美的只是稍微改动一下,这样我就可以让每个医院名称都有自己的图表,你能更新代码给每个医院自己的图表吗? 然后我的输出栏高度数给出了一个非常长的十进制数,例如 452.05263157894734,我在想我是否也可以将其缩短为整数 452以上是关于在 Jupyter Notebook 上清理并制作可读的条形图的主要内容,如果未能解决你的问题,请参考以下文章
Windows10 环境下Jupyter Notebook的安装与使用