​​一、概论

1.Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时甚至数天的工作时间.

2.pyecharts实现数据大屏需要运用到page组件和bs4库。

  • 实现步骤如下:
  • 1、生成各个图形及其对象
  • 2、通过page组件将多个图形展示出来,生成html文件。
  • 3、通过bs4库修改html文件种图形位置等相关设置,将图形调整成一个合适、美观的数据大屏的形式。

二、用到的组件

  • 首先画图用到pyecharts库,要在cmd里面安装
pip install pyecharts
  • 本案例还使用到jieba库和snownlp
pip install jieba
pip install snownlp

三、map地图

  • 基本格式
  • 数据可视化项目中,地图的展示也是经常用到的展示项之一。某些项目,地图展示效果甚至整个项目中最关键的部分,直接决定了产品质量的优略。
c=(
   Map()
   .add("",data,"china")
   .sot_global_opts(title_opts=opts.TitleOpts(title="Map 基本示例"),
                    visualmap opts=opts.VisualMapOpts(),#色阶配置项
                    )
)
c.render_notebook()

四、词云图

  1. 从一段文字到一个词云图形的过程中,还应该包含将一个长文本拆分成多个词汇以及统计每个词汇出现的频次这两个步骤。
  2. 第一个步骤我们叫做”分词“,在python有很多第三方库可以实现长文本的分词。常见的分词库有:jieba、snownlp(见第二点安装)
  3. 基本格式
w=(
   WordCloud()
   .add(series_name="",data_pair=data,word_size_range=[6,66])
   .set_glbal_opts(
        title_opts=opts.TitleOpts(
             title="",title_textstyle_opts=opts.TextStyleOpts(font_size=23)
        ),
        tooltip_opts=opts.ToolyipOpts(is_show=True),
    )

    .render("wordcloud.html")
)

五、玫瑰图

  • 玫瑰图又名鸡冠花图、极坐标区域图,是极坐标化的柱图,可以将其理解为披着饼图外皮的柱状图。其制作原理是将极坐标平面分为若干等角区域,再依据数据大小不同,把相应的等角区域进行填充,使不同大小的等角区域构成一片片花瓣,玫瑰图也就由此而来
  • 玫瑰图:在饼图的基础上,每一块饼的半径表示该区域的数据大小。
  • 基本格式
Pie()
.add(
     "",
     [list(z) for z in zip(v,Faker,values())],
     radius=["30%","75%"],
     center=["25%","50%"],
     rosetype="radius",
     label_opts=opts.LabelOpts(is_show=False),
)

六、3D图

  • 3D图需要3个不同维度的列表,但是绘制完成后可以从不同的投影面分析(不考虑xyz某一轴,单看另外两轴, 可以比较三次,方便储存,最终以html的形式保存,并且附带相关交互功能

  • Bar3D类创建3D图对象

  • add方法添加数据:

  • (1)data参数中输入z轴数据(需要一个n*3形状的二维列表,n是柱体的个数)

  • (2)xaxis3d_opts 和 yaxis3d_opts分别输入x轴和y轴刻度值

用3D图画一个中国地图:

from pyecharts import options as opts
from pyecharts.charts import Map3D
from pyecharts.globals import ChartType

c = (
    Map3D(init_opts=opts.InitOpts(width='1300px', height='1300px',bg_color='#EBEBEB'))

    .add_schema(
        itemstyle_opts=opts.ItemStyleOpts(
            color="#CDBA96",
            opacity=1,
            border_width=0.8,
            border_color="rgb(62,215,213)",
        ),
        map3d_label=opts.Map3DLabelOpts(
            is_show=True,
            text_style=opts.TextStyleOpts(
                color="#104E8B", font_size=16, background_color="rgba(0,0,0,0)"
            ),
        ),
        emphasis_label_opts=opts.LabelOpts(is_show=True),
        light_opts=opts.Map3DLightOpts(
            main_color="#FFEBCD",
            main_intensity=1.2,
            is_main_shadow=False,
            main_alpha=55,
            main_beta=10,
            ambient_intensity=0.3,
        ),
    )
    .add(series_name="", data_pair="", maptype=ChartType.MAP3D)
    # 全局设置地图属性
    .set_global_opts(
        title_opts=opts.TitleOpts(title="全国行政区划地图"),
        visualmap_opts=opts.VisualMapOpts(is_show=False),
        tooltip_opts=opts.TooltipOpts(is_show=True),
    )
    .render("map3d_china_base.html")
)

运行结果如下:


七、标题

  • 在制作可视化大屏时要先制作一个标题,且这个标题必须以饼图的格式来制作,因为用其他的图形,例如:柱形图,会自动出现一个x,y坐标轴;
from pyecharts.charts import Pie
from datetime import datetime
now_time = datetime.now().strftime('%Y-%m-%d') # 获取当前时间
big_title = (
    Pie() # 不画图,只显示一个标题,用来构成大屏的标题
        .set_global_opts(
        title_opts=opts.TitleOpts(title="图形大屏标题",
                                  title_textstyle_opts=opts.TextStyleOpts(font_size=40,
#                                                                           color='#FFFFFF',
                                                                         ),
                                  subtitle = f'截至:{now_time}',
                                  pos_top=10
                                 )
        )
)
big_title.render_notebook()

八、page组件

  • page组件是制作可视化大屏的 必要,它会连续展现多个图形;
  • 在使用page组件时会涉及到jinja2的版本,要先进行更新
pip install --upgrade jinja2

九、调试

  • 为了运行结果更加美观,我们用到bs4库的BeautifulSoup来进行界面调试
from bs4 import BeautifulSoup
with open("page.html", "r+", encoding='utf-8') as html:
    html_bf = BeautifulSoup(html, 'lxml')
    divs = html_bf.select('.chart-container') # 根据css定位标签,选中图像的父节点标签
    divs[0]["style"] = "width:420px;height:55px;position:absolute;top:20px;left:600px;border-style:dashed;border-color:#444444;border-width:0px;"
    divs[1]["style"] = "width:420px;height:274px;position:absolute;top:100px;left:30px;border-style:solid;border-color:#444444;border-width:2px;"
    divs[2]["style"] = "width:420px;height:274px;position:absolute;top:100px;left:470px;border-style:solid;border-color:#444444;border-width:2px;"
    divs[3]["style"] = "width:420px;height:274px;position:absolute;top:100px;left:910px;border-style:solid;border-color:#444444;border-width:2px;"
    body = html_bf.find("body") # 根据标签名称定位到body标签
    body["style"] = "background-color:white;" # 修改背景颜色
    html_new = str(html_bf) # 将BeautifulSoup对象转换为字符
    html.seek(0, 0) # 光标移动至
    html.truncate() # 删除光标后的所有字符内容
    html.write(html_new) # 将由BeautifulSoup对象转换得到的字符重新写入html文件
    html.close()

十、案例展示

  • 使用4个pyecharts图形画一个可视化大屏
  • 要求图形是2*2排布的,有一个大屏标题

1.先使用pyecharts画四个基本图形

(1)地图
from pyecharts import options as opts
from pyecharts.charts import Map
import pandas as pd

df=pd.read_excel('E:/蒋雪玲/数据集/各省份车辆销售数量.xlsx')#导入数据
df 

provinces = ['广西壮族自治区','山东省','河南省','江苏省','山西省','河北省','浙江省','广东省','云南省','四川省','安徽省','湖北省','湖南省','上海市','福建省','陕西省','贵州省','天津市','江西省','海南省','重庆市','北京市','新疆维吾尔族自治区','内蒙古自治区','辽宁省','甘肃省','黑龙江省','西藏自治区','青海省']
values = [67663,6016,3148,1470,1409,1183,993,768,749,524,453,443,372,351,351,324,305,295,248,207,201,99,18,9,5,3,2,1,1]
data = [list(z) for z in zip(provinces, values)]
data

#画图
pieces = [
    {'max': 100, 'label': '100以下', 'color': 'yellow'},
    {'min': 100, 'max': 1000, 'label': '1000以下', 'color': 'yellow'},
    {'min': 1000, 'max': 10000, 'label': '10000以下', 'color': 'orange'},
    {'min': 10000, 'label': '10000以上', 'color': 'red'}  # 有下限无上限
]
map = (
    Map()
    .add("", data , "china")
    .set_global_opts(title_opts=opts.TitleOpts(title="各省车辆销售数量地图"),
                     visualmap_opts=opts.VisualMapOpts(
                         is_piecewise=True,
                         pieces=pieces
                     ), # 色阶配置项,用颜色表示数字大小
                    )
)
map.render_notebook()

运行结果如下:

(2)词云图(这里用到jieba和snownlp库)
import pandas as pd
import jieba
from snownlp import SnowNLP 
import pyecharts.options as opts
from pyecharts.charts import WordCloud

#先处理数据
data = pd.read_excel('E:/蒋雪玲/pyecharts/豆瓣剧情片排行榜.xlsx')
data
data['词性标注'] = data['title'].agg(lambda x:list(SnowNLP(x).tags))
data

list_tags = []
for i in data['词性标注']:
    for j in i:
        list_tags.append(j)
list_tags

data_tags = pd.DataFrame(list_tags,columns=['词语','词性'])
data_tags

data_tags['词性']

result = data_tags[data_tags['词性']=='n'].groupby(by='词语')['词语'].count().sort_values(ascending=False)#[:20]
result

data_wordcloud_tags = [(i,str(j)) for i,j in zip(result.index,result.values)]
data_wordcloud_tags

#画图
wordcloud = (
    WordCloud()
    .add(series_name="", 
         data_pair=data_wordcloud_tags, 
         word_size_range=[30, 100]
        )
    .set_global_opts(
        title_opts=opts.TitleOpts(
            title="电影", title_textstyle_opts=opts.TextStyleOpts(font_size=23)
        ),
        tooltip_opts=opts.TooltipOpts(is_show=True),
    )
)
wordcloud.render_notebook()

运行结果如下:

(3)玫瑰图
from pyecharts.charts import Pie
from pyecharts import options as opts
import pandas as pd

df=pd.read_excel('E:/蒋雪玲/数据集/航空公司数据.xlsx')
df

#年龄分箱
df['年龄段']=pd.cut(
    df['年龄'],
    bins=[0,20,40,60,100],
    labels=['少年','青年','中年','老年']
)
#分组统计
result=df.groupby('年龄段').size()
#数据准备
data = [[x,int(y)]for x,y in zip(result.index,result.values)]

#画图
pie=(
    Pie()
    .add(
        '',#数据的系列名称,如果只有一个系列的数据,填空字符
        data,
        radius=['30%','75%'],
        center=['25%','50%'],
        rosetype='radius'
    )
)
pie.render_notebook()

运行结果如下:

(4)、3D图
from pyecharts.charts import *
from pyecharts import options as opts
from pyecharts.faker import Faker
import numpy as np
import math
 
data = []
for t in range(0, 25000):
    _t = t/1000
    x = (1 + 0.25 * math.cos(75 * _t)) * math.cos(_t)
    y = (1 + 0.25 * math.cos(75 * _t)) * math.sin(_t)
    z = _t + 2 * math.sin(75 * _t)
    data.append([x, y, z])
# print(np.array(data).shape)  # 查看列表的维度
 
line = (
    Line3D()
    .add('',
         data,
         xaxis3d_opts=opts.Axis3DOpts(Faker.clock, type_='value'),
         yaxis3d_opts=opts.Axis3DOpts(Faker.week, type_='value'),
         grid3d_opts=opts.Grid3DOpts(width=100,  # 宽度
                                     depth=100,  # 深度
                                     rotate_speed=150,  # 旋转速度
                                     # is_rotate=True,    # 是否自动旋转
                                     )
         )
    .set_global_opts(visualmap_opts=opts.VisualMapOpts(min_=0,  # 视觉映射最小值
                                                       max_=30,  # 视觉映射最大值
                                                       range_color=Faker.visual_color  # 颜色范围
                                                       )
                     )
)
line.render_notebook()

运行结果如下:

(5)、大屏标题
from pyecharts.charts import Pie
from datetime import datetime
now_time = datetime.now().strftime('%Y-%m-%d') # 获取当前时间
big_title = (
    Pie() # 不画图,只显示一个标题,用来构成大屏的标题
        .set_global_opts(
        title_opts=opts.TitleOpts(title="图形大屏标题",
                                  title_textstyle_opts=opts.TextStyleOpts(font_size=40,
#                                                                           color='#FFFFFF',
                                                                         ),
                                  subtitle = f'截至:{now_time}',
                                  pos_top=10
                                 )
        )
)
big_title.render_notebook()

运行结果:(生成一个标题)

(6)、使用page组件将以上图形添加
from pyecharts.charts import Page

page = Page()
page.add(
    big_title,
    map,
    wordcloud,
    pie,
    line,
)
# page.render_notebook()
page.render('图形数据大屏.html')

会得到以下运行结果:

(7)、这时我们要使用BeautifulSoup来进行界面调试,使图片更加美观
from bs4 import BeautifulSoup
with open("图形数据大屏.html", "r+", encoding='utf-8') as html:
    html_bf = BeautifulSoup(html, 'lxml')
    divs = html_bf.select('.chart-container') # 根据css定位标签,选中图像的父节点标签
    divs[0]["style"] = "width:600px;height:100px;position:absolute;top:0px;left:450px;border-style:dashed;border-color:#444444;border-width:0px;"
    divs[1]["style"] = "width:500px;height:250px;position:absolute;top:50px;left:30px;border-style:dashed;border-color:#444444;border-width:2px;"
    divs[2]["style"] = "width:500px;height:250px;position:absolute;top:50px;left:600px;border-style:dashed;border-color:#444444;border-width:2px;"
    divs[3]["style"] = "width:500px;height:250px;position:absolute;top:330px;left:30px;border-style:dashed;border-color:#444444;border-width:2px;"
    divs[4]["style"] = "width:500px;height:250px;position:absolute;top:330px;left:600px;border-style:dashed;border-color:#444444;border-width:2px;"
    
    body = html_bf.find("body") # 根据标签名称定位到body标签
    body["style"] = "background-color:withe;" # 修改背景颜色
    html_new = str(html_bf) # 将BeautifulSoup对象转换为字符
    html.seek(0, 0) # 光标移动至
    html.truncate() # 删除光标后的所有字符内容
    html.write(html_new) # 将由BeautifulSoup对象转换得到的字符重新写入html文件
    html.close()

运行得到以下:


十一、总结

  • 提高数据可视度:通过图表、图像等形式展示数据,使数据更加直观易懂,提高数据的可视度。
  • 增强数据交互性:通过Echarts提供的交互功能,用户可以与图表进行交互,实现数据的探索和分析。
  • 提升决策效率:通过数据可视化大屏展示,可以快速了解数据的整体情况和趋势,为决策提供支持。
  • pyecharts是一个基于echarts的Python可视化库,它提供了一系列丰富多样的图表类型和样式,可以轻松地生成漂亮而又具有交互性的图表。

感谢各位读者的阅读,文章作者技术和水平有限,如果文中出现错误,希望大家能指正!

Logo

永洪科技,致力于打造全球领先的数据技术厂商,具备从数据应用方案咨询、BI、AIGC智能分析、数字孪生、数据资产、数据治理、数据实施的端到端大数据价值服务能力。

更多推荐