python DataFrame转换成柱状图html代码

      之前写了个服务器磁盘监控的脚本,每天将磁盘的使用情况通过电子邮件发送出来,通过paramiko.SSHClient()将磁盘使用情况报错到一个DataFrame对象中,然后通过DataFrame的实例方法to_html直接转换成html,最后通过MIMEText发送html到邮箱中。

      通过以上方法,在邮件正文中看到的是表格,在服务器较多时,不够直观。所以想改造成直接显示柱状图。但是邮件正文一般都无法运行js代码,所以使用js写的表格转换柱状图无法使用,所以只能用纯html来实现。

从Hadoop 50070页面的磁盘状况表格中得到灵感,可以使用表格嵌套和背景颜色来实现柱状图。下图中Used列,就是还有表格嵌套来实现的柱状图,我只需将横向柱状转换成纵向即可。


先收到写也demo

<!--这是一个用表格嵌套来实现两个标签的柱状图demo-->
<br>10.1.1.1<br>
<table border="1px" style="table-layout:fixed >
<tbody border="1px" width="100px" height="200px" >
	<!--柱状图1-->
	<td>	
		<table border="1px" width="100px" height="200px">
			<tbody>
			 <tr>
			  <td  height =""  cellspacing="0" class="perc_filled"  bgcolor="" align="center"></td>
			 </tr>
			 <tr>
			  <td  height ="99%" cellspacing="0" class="perc_filled"  bgcolor="#FF0000" align="center">99%</td>
			 </tr>
			</tbody>
		</table>
	</td>
	<!--柱状图2-->
	<td>	
		<table border="1px" width="100px" height="200px">
			<tbody>
			 <tr>
			  <td  height ="" cellspacing="0" class="perc_filled"  bgcolor="" style="word-break:break-all;" align="center"></td>
			 </tr>
			 <tr>
			  <td  height ="0%" cellspacing="0" class="perc_filled"  bgcolor="#FF0000" style="word-break:break-all;" align="center" >0%</td>
			 </tr>
			</tbody>
		</table>
	</td>
	<tr>
	<!--标签-->
	<td  style="word-break:break-all;" align="center" >/</td>
	<td  style="word-break:break-all;" align="center" >/opt/data01</td>
	</tr>
</tbody>
</table>

demo的效果如下:


这个demo还有一些问题,比如使用率为0%是,显示的却为一半,这个在实际的代码中解决。

先设计一个函数,接收两个参数,一个是柱状图的标题,如上面的10.1.1.1,另一个参数是DataFrame对象,这个对象包含两列,第一列是数据标签,第二列是数据,第二列的数据格式为带符合的比例数据:如50%。

因为可能会有多个挂载点,且数量不一定。所以需要一个html模板,然后通过format方法替换模板中的占位符。

python代码如下:

扫描二维码关注公众号,回复: 2094189 查看本文章
# -*- coding: utf-8 -*-
"""
Created on %(2018-01-20)s

@author: %(周小科)s
"""
import pandas as pd
import numpy as np
html_modle="""
<br><b>{title}</b><br>
<table border="1px" style="table-layout:fixed >
<tbody border="1px" width="100px" height="200px" >
              <!--<td height =""  cellspacing="0" class="perc_filled"  bgcolor="" align="center"> 使用率</td> -->
    	{histogramTdHtml}
	<tr>
               <!--<td  style="word-break:break-all;" align="center" >挂载点</td> -->
	{labHtml}
	</tr>
</tbody>
</table>


"""

histogramTdHtmlTempletNonzero="""
	<td>	
		<table  width="100px" height="200px">
			<tbody>
			 <tr>
			  <td  height =""  cellspacing="0" class="perc_filled"  bgcolor="" align="center"></td>
			 </tr>
			 <tr>
			  <td  height ="{percent}" cellspacing="0" class="perc_filled"  bgcolor="{color}" align="center">{percentText}</td>
			 </tr>
			</tbody>
		</table>
	</td>
"""

histogramTdHtmlTempletZero="""
	<td>	
		<table  width="100px" height="200px">
			<tbody>
			 
			</tbody>
		</table>
	</td>
"""

labHtmlTemplet="""
            <td  style="word-break:break-all;" align="center" >{lable}</td>
"""


def DataFrame2HistogramHtml(title,df):
    """
    将pandas中的DataFrame转换成柱状图html代码
    title:标题。这个图的标题
    df:传入DataFrame对象,要求这个对象有两列,第一列是标签,第二列是百分比数据,带%的 入 50%。index必须从0开始
    
    """
    pd.DataFrame()
    histogramTdHtml=""
    labHtml=""
    ##大于一个阈值,就用红色或橙色显示
    for i  in range(0,len(df)):
        lable=df.loc[i][0]
        percent=df.loc[i][1]
        percentText=percent
        percentData=int(percent.replace("%",""))
        #print(percentData)
        #print("print(percent)",percent)
        labHtml=labHtml+labHtmlTemplet.format(lable=lable)
        color="#0099FF"
        
        #默认是条形图颜色为蓝色,如果超过50%则为黄色,如果超过90%则为红色
        if(percentData>90):
            color="#FF0000"
        elif(percentData>50):
            color="#FFCC00"
            
        
        #如果百分比为0%,则使用histogramTdHtmlTempletZero模板
        if(percentData==0):
            #print(percent)
            histogramTdHtmlTemplet=histogramTdHtmlTempletZero
            percentText=""
        elif(percentData<10):
            histogramTdHtmlTemplet=histogramTdHtmlTempletNonzero
            percentText=""
        else:
            histogramTdHtmlTemplet=histogramTdHtmlTempletNonzero
            
        histogramTdHtml=histogramTdHtml+histogramTdHtmlTemplet.format(percent=percent,color=color,percentText=percentText)
        
    #print(histogramTdHtml)
    #print(labHtml)
    html=html_modle.format(title=title,histogramTdHtml=histogramTdHtml,labHtml=labHtml)
    #print(html)
    return html
    
    
def main():
    s1=pd.Series(np.array(["a","b","c","d","e"]))
    s2=pd.Series(np.array(["51%","0%","50%","1%","91%"]))
    df=pd.DataFrame({"m":s1,"u":s2});
    print(df)
    print(len(df))
    for i  in range(1,len(df)+1):
        print(i)
    html=DataFrame2HistogramHtml("10.1.1.1",df)
    f=open(r"C:\histogramTdHtml.html","w")
    f.write(html)
    f.close
if __name__=='__main__':
    #RESULT_STR=''
    main()

    
    
    
    
    
    
    
    
    
    
   
    

该代码中包含了调试数据,可以直接运行(前提是装了pandas、numpy库),并将html代码写入C:\histogramTdHtml.html 读者可以自行修改main方法中的测试代码。测试效果如下:


这个方法也还有写待改进的地方,比如柱状图的高和宽,可以参数化,使其可以更加通用。目前高和宽是在html模板中写死的,如果需要调整,会比较麻烦


猜你喜欢

转载自blog.csdn.net/cakecc2008/article/details/79114456
今日推荐