Plot table alongside sns.barplot

2019-07-20 09:18发布

问题:

#read data into dataframe
con=pd.read_csv('testOutput.csv')

'''
testOutput.csv looks like :
Sample,Count
sample1,99.9
sample2, 96.6
'''


## set colours to increase with values
sns.set(style="darkgrid")
groupedvalues=con.groupby("Count").sum().reset_index()
pal = sns.color_palette("Greens_d", len(groupedvalues))
rank = groupedvalues["Count"].argsort().argsort()

#get summary stats of data
summary=pd.DataFrame(con['Count'].describe())
#set limits
maxLim=100
minLim=min(con['Count'])-0.1
#barplot horizontal
g=sns.barplot(x='Count', y ='Sample',data=groupedvalues,  palette=np.array(pal[::-1])[rank])
plt.xlim(minLim,maxLim)
plt.xticks(np.arange(minLim, 100, 0.1))
#remove labels
g.set(yticks=[])

g.set(xlabel='BLA BLA BLA', ylabel='Sample')
plt.table(cellText=summary.values,
          rowLabels=summary.index,
          colLabels=summary.columns,
          cellLoc = 'center', rowLoc = 'center',
          loc='right')
#plt.show()
plt.savefig('outTest.png', dpi=150)

This outputs : This table on the right of the image is cut off. How do I fix this and also just round down to nearest 0.1 on the labels please?

Thanks

回答1:

In principle, the same strategies than in this question's answer apply here.

Using bbox

You may freely position the table on your graph using the bbox argument, bbox = [left, bottom, width, height] where left, bottom, width, height are fractions of the axes.

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

df = pd.DataFrame({"count" : np.sort(np.random.rand(100))*100})

summary=pd.DataFrame(df['count'].describe())

plt.barh(range(len(df)),df["count"])

plt.table(cellText=summary.values,
          rowLabels=summary.index,
          colLabels=summary.columns,
          cellLoc = 'right', rowLoc = 'center',
          loc='right', bbox=[.65,.05,.3,.5])

plt.savefig("out.png")
plt.show()

This would also allow to put the table outside the axes by choosing the paramters larger than 1. In order to make space for the table, you can then shrink the subplots, plt.subplots_adjust(right=0.75).

plt.table(cellText=summary.values,
          rowLabels=summary.index,
          colLabels=summary.columns,
          cellLoc = 'right', rowLoc = 'center',
          loc='right', bbox=[1,.3,.3,.5])

plt.subplots_adjust(right=0.75)

Using dedicated subplot

You may use a dedicated subplot to put the table in.

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

df = pd.DataFrame({"count" : np.sort(np.random.rand(100))*100})

summary=pd.DataFrame(df['count'].describe())

fig,(ax,tabax) = plt.subplots(ncols=2, gridspec_kw=dict(width_ratios=[2,1]))
ax.barh(range(len(df)),df["count"])

tabax.axis("off")
tabax.table(cellText=summary.values,
          rowLabels=summary.index,
          colLabels=summary.columns,
          cellLoc = 'right', rowLoc = 'center',
          loc='center')

plt.savefig("out.png")
plt.show()