matplotlib 如何自定义Pandas盒和胡须图与额外的拼图?

kyvafyod  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(129)

我试图产生以下情节,这是在Excel中,通过使用Pandas。
x1c 0d1x的数据
工作中的很多绘图都是用excel完成的,把数据转换成所需的格式既繁琐又乏味。我想用pandas,但我的老板希望看到完全相同(或非常接近)的绘图。
我通常使用海运箱线图,发现它非常方便,但我需要显示更多的条纹(第5,第10,第25,第50,第75,第90和第95),如图图例所示。
我知道seaborn/matplotlib允许我使用whis=[10,90]来改变胡须的范围,我可以使用showmean=True,但这会留下其他标记(第95和第5个胡须)添加到每个图中。如何覆盖这些标记?
我将数据按我想要的方式分组,并且可以使用.describe()提取数据,如下所示pcntls=assay.groupby(['LocalSTRAT']).describe(percentiles=[0.1,0.05,0.25,0.5,0.75,0.9,0.95])
和转换,这给了我这个:

LocalSTRAT  AB  CBC     CLB     LAB     LBB     LBL     MS  TB  TBL     UAB     UBB
count   982.000000  234.000000  159.000000  530.000000  1136.000000     72.000000   267.000000  1741.000000     16.000000   1641.000000     2099.000000
mean    0.687658    1.410962    0.118302    0.211321    0.110251    0.077917    0.766124    0.262648    0.191875    0.119174    1.320357
std     0.814027    0.855342    0.148397    0.286574    0.146550    0.088921    0.647259    0.309134    0.125497    0.207197    1.393613
min     0.005000    0.005000    0.020000    0.005000    0.005000    0.010000    0.005000    0.005000    0.060000    0.005000    0.005000
5%  0.030000    0.196500    0.030000    0.020000    0.020000    0.020000    0.060000    0.020000    0.067500    0.005000    0.170000
10%     0.050000    0.363000    0.038000    0.020000    0.020000    0.021000    0.096000    0.030000    0.070000    0.020000    0.230000
25%     0.130000    0.825000    0.045000    0.050000    0.030000    0.030000    0.225000    0.050000    0.077500    0.030000    0.450000
50%     0.400000    1.260000    0.070000    0.120000    0.050000    0.050000    0.610000    0.150000    0.175000    0.060000    0.940000
75%     0.950000    1.947500    0.140000    0.250000    0.120000    0.072500    1.120000    0.350000    0.257500    0.130000    1.570000
90%     1.720000    2.411000    0.262000    0.520000    0.265000    0.149000    1.624000    0.640000    0.340000    0.250000    2.770000
95%     2.370000    2.967500    0.322000    0.685500    0.390000    0.237000    2.037000    0.880000    0.390000    0.410000    4.322000
max     7.040000    5.070000    1.510000    2.620000    1.450000    0.580000    3.530000    2.390000    0.480000    4.190000    11.600000

字符串
我被如何使用这个输出从零开始开始构建箱线图所困扰。
我认为以正常的方式构建一些箱线图更容易,然后在顶部添加额外的几个数据点(第5和第95百分位数标记),但不知道如何做到这一点。
(加分的方法,使一个像一个显示或如何插入一个图像文件,这到我的阴谋,并获得日志风格的网格线,并包括在x轴的计数!)

hrysbysz

hrysbysz1#

只需使用从.describe()输出中提取的图例覆盖散点图,记住对两者进行排序以确保顺序不会混淆。图例是作为外部图像制作的,并单独插入。
使用plt.text()计算并添加计数。
使用plt.grid(True, which='both')应用对数网格线并将轴设置为log。
下面的代码和结果。

import pandas as pd
import seaborn as sns
import matplotlib
import matplotlib.pyplot as plt

pathx = r"C:\boxplots2.xlsx"

pathx =  pathx.replace( "\\", "/")#avoid escape character issues
#print pathx
#pathx = pathx[1:len(pathx)-1]
df=pd.read_excel(pathx)

#this line removes missing data rows (where the strat is not specified)
df=df[df["STRAT"]!=0]


assay=df

factor_to_plot='Total %S'
f=factor_to_plot

x_axis_factor='STRAT'
g=x_axis_factor

pcntls=assay.groupby([g]).describe(percentiles=[0.05,0.1,0.25,0.5,0.75,0.9,0.95])
sumry= pcntls[f].T
#print sumry
ordered=sorted(assay[g].dropna().unique())

#set figure size and scale text
plt.rcParams['figure.figsize']=(15,10)
text_scaling=1.9
sns.set(style="whitegrid")
sns.set_context("paper", font_scale=text_scaling) 

#plot boxplot
ax=sns.boxplot(x=assay[g],y=assay[f],width=0.5,order=ordered, whis=[10,90],data=assay, showfliers=False,color='lightblue', 
            showmeans=True,meanprops={"marker":"x","markersize":12,"markerfacecolor":"white", "markeredgecolor":"black"})

plt.axhline(0.3, color='green',linestyle='dashed', label="S%=0.3")

#this line sets the scale to logarithmic
ax.set_yscale('log')

leg= plt.legend(markerscale=1.5,bbox_to_anchor=(1.0, 0.5) )#,bbox_to_anchor=(1.0, 0.5)
#plt.title("Assay data")
plt.grid(True, which='both')
ax.scatter(x=sorted(list(sumry.columns.values)),y=sumry.loc['5%'],s=120,color='white',edgecolor='black') 
ax.scatter(x=sorted(list(sumry.columns.values)),y=sumry.loc['95%'],s=120,color='white',edgecolor='black')

#add legend image
img = plt.imread("legend.jpg")
plt.figimage(img, 1900,900, zorder=1, alpha=1)

#next line is important, select a column that has no blanks or nans as the total items are counted. 
assay['value']=assay['From']

vals=assay.groupby([g])['value'].count()
j=vals

ymin, ymax = ax.get_ylim()
xmin, xmax = ax.get_xlim()
#print ymax

#put n= values at top of plot    
x=0
for i in range(len(j)):

    plt.text(x = x , y = ymax+0.2, s = "N=\n" +str(int(j[i])),horizontalalignment='center')
    #plt.text(x = x , y = 102.75, s = "n=",horizontalalignment='center')
    x+=1



#use the section below to adjust the y axis lable format to avoid default of 10^0 etc for log scale plots.
ylabels = ['{:.1f}'.format(y) for y in ax.get_yticks()]
ax.set_yticklabels(ylabels)

字符串
该公式给出:


的数据

相关问题