Python通过Flask+pyecharts对房地产数据实现数据分析结果Web可视化(二)

news2024/11/19 13:23:58

一、背景

在Python通过pyecharts对爬虫房地产数据进行数据可视化分析(一)基础上添加Flask框架实现web可视化功能,把生成的所有图表生成一份完整的数据分析报告,这样就可以方便直接在网页上看到整体的数据分析可视化结果。

二、步骤实现

这个步骤的实现主要包括如下三个部分组成:

  1. 用flask库实现的app.py脚本,这个脚本主要干如下几件事:
  • 启动一个web服务;
  • 读取我们要分析的原始数据;
  • 实现一个函数负责将读取的数据传给不同的数据图表生成函数,拿到生成的数据图表对象,然后调用模版进行渲染;
  • 绑定一个url路由关系,映射到步骤三的函数;
  1. 用来渲染生成最终数据分析报告的HTML文件,这个文件主要干如下几件事:
  • 对每个数据图表定义一个div;
  • 使用ECharts组件对div进行初始化;
  • 通过变量拿到flask返回的数据图表数据,对ECharts组件进行设置;
  1. HTML渲染和计算所依赖的静态资源文件,主要有如下三个:
  • echarts-wordcloud.min.js,主要用于词云图生成;
  • hu2_bei3_wu3_han4.js,主要用于苏州地图生成;
  • echarts.min.js,是所有数据图表依赖的基础js;

如上三个部分需要按照如下的代码目录结构来组织:
在这里插入图片描述

三、代码实现

数据分析主体代码文件为:drawCharts.py,与之前的在最后稍微有点不同,把最后的主函数部分注释掉就好了

"""
读取excel数据,分析数据并生成图表
"""

# -*- coding: UTF-8-*-

import pandas as pd
from pyecharts import options as opts
from pyecharts.charts import Bar, Pie, Scatter, WordCloud, Map, Page
import numpy as np
import jieba
import jieba.analyse
from pyecharts.commons.utils import JsCode



def cal_square_district(row):
    if row['面积'] <= 60:
        return '[0,60]'
    if row['面积'] > 60 and row['面积'] <= 90:
        return '[60,90]'
    if row['面积'] > 90 and row['面积'] <= 120:
        return '[90,120]'
    if row['面积'] > 120 and row['面积'] <= 150:
        return '[120,150]'
    if row['面积'] > 150 and row['面积'] <= 200:
        return '[150,200]'
    if row['面积'] > 200 and row['面积'] <= 300:
        return '[200, 300]'
    if row['面积'] > 300:
        return '[300,-]'
    return '[未知]'


def order_layout_ascending(row):
    if row['室'] == '1室':
        return 0
    if row['室'] == '2室':
        return 1
    if row['室'] == '3室':
        return 2
    if row['室'] == '4室':
        return 3
    if row['室'] == '5室':
        return 4
    if row['室'] == '6室':
        return 5


layout_color_function = """
        function (params) {
            if (params.value > 17000 && params.value < 18000) {
                return 'red';
            } else if (params.value > 18000 && params.value < 20000) {
                return 'blue';
            }else if (params.value > 20000 && params.value < 25000){
                return 'green'
            }else if (params.value > 25000 && params.value < 35000){
                return 'purple'
            }else if (params.value > 35000 && params.value < 40000){
                return 'black'
            }
            return 'brown';
        }
        """


def unit_price_analysis_by_layout(df, isembed):
    # 增加一列[面积区间]
    df['面积区间'] = df.apply(cal_square_district, args=(), axis=1)
    # 获取要分析的数据行和列
    analysis_df = df.loc[:, ['室', '均价']]
    analysis_df.loc[:, '室'] = analysis_df.loc[:, '室'].astype('str')
    # 对面积区间列group by,然后按分组计算总价和均价的平均值
    group = analysis_df.groupby('室', as_index=False)
    group_df = group.mean()
    group_df.loc[:, '均价'] = group_df.loc[:, '均价'].astype('int')
    # 给室这个字段排个序
    group_df['order'] = group_df.apply(order_layout_ascending, axis=1)
    group_df.sort_values('order', ascending=True, inplace=True)

    bar = (
        Bar()
            .add_xaxis(group_df['室'].tolist())
            .add_yaxis("单价均价", group_df["均价"].tolist(),
                       itemstyle_opts=opts.ItemStyleOpts(color=JsCode(layout_color_function)))
            .set_global_opts(title_opts=opts.TitleOpts(title="武汉二手房按户型的房屋单价"),
                             legend_opts=opts.LegendOpts(is_show=False))
    )

    # 判断是否单独显示,还是和其他图表一起显示
    if isembed:
        return bar.render_embed()
    else:
        return bar


def order_square_ascending(row):
    if row['面积区间'] == '[0,60]':
        return 0
    if row['面积区间'] == '[60,90]':
        return 1
    if row['面积区间'] == '[90,120]':
        return 2
    if row['面积区间'] == '[120,150]':
        return 3
    if row['面积区间'] == '[150,200]':
        return 4
    if row['面积区间'] == '[200,300]':
        return 5
    if row['面积区间'] == '[300,-]':
        return 6


square_color_function = """
        function (params) {
            if (params.value > 17000 && params.value < 18000) {
                return 'red';
            } else if (params.value > 18000 && params.value < 20000) {
                return 'blue';
            }else if (params.value > 20000 && params.value < 25000){
                return 'green'
            }else if (params.value > 25000 && params.value < 35000){
                return 'purple'
            }else if (params.value > 35000 && params.value < 40000){
                return 'black'
            }
            return 'brown';
        }
        """


def unit_price_analysis_by_square(df, isembed):
    # 增加一列[面积区间]
    df['面积区间'] = df.apply(cal_square_district, args=(), axis=1)
    # 获取要分析的数据行和列
    analysis_df = df.loc[:, ['面积区间', '均价']]
    analysis_df.loc[:, '面积区间'] = analysis_df.loc[:, '面积区间'].astype('str')
    # 对面积区间列group by,然后按分组计算总价和均价的平均值
    group = analysis_df.groupby('面积区间', as_index=False)
    group_df = group.mean()
    group_df.loc[:, '均价'] = group_df.loc[:, '均价'].astype('int')
    # 把面积区间按从小到大排个序
    group_df['order'] = group_df.apply(order_square_ascending, axis=1)
    group_df.sort_values('order', ascending=True, inplace=True)


    bar = (
        Bar()
            .add_xaxis(group_df['面积区间'].tolist())
            .add_yaxis("单价均价", group_df["均价"].tolist(),
                       itemstyle_opts=opts.ItemStyleOpts(color=JsCode(square_color_function)))
            .set_global_opts(
            title_opts=opts.TitleOpts(title="武汉二手房按面积区间的房屋单价"),
            legend_opts=opts.LegendOpts(is_show=False))
    )

    # 判断是否单独显示,还是和其他图表一起显示
    if isembed:
        return bar.render_embed()
    else:
        return bar


top10_color_function = """
        function (params) {
            if (params.value > 27000 && params.value < 27500) {
                return 'red';
            } else if (params.value > 27500 && params.value < 27800) {
                return 'blue';
            }else if (params.value > 27800 && params.value < 28000){
                return 'green'
            }else if (params.value > 28000 && params.value < 29000){
                return 'purple'
            }else if (params.value > 29000 && params.value < 30000){
                return 'brown'
            }else if (params.value > 30000 && params.value < 35200){
                return 'gray'
            }else if (params.value > 35200 && params.value < 37000){
                return 'orange'
            }else if (params.value > 37000 && params.value < 40000){
                return 'pink'
            }else if (params.value > 40000 && params.value < 45000){
                return 'navy'
            }
            return 'gold';
        }
        """


def unit_price_analysis_by_estate(df, isembed):
    # 获取要分析的数据列
    analysis_df = df.loc[:, ['小区名称', '均价']]
    analysis_df.loc[:, '小区名称'] = analysis_df.loc[:, '小区名称'].astype('str')
    # 对小区名称分组,然后按照分组计算单价均价
    group = analysis_df.groupby('小区名称', as_index=False)
    group_df = group.mean()
    group_df.loc[:, '均价'] = group_df.loc[:, '均价'].astype('int')
    # 按照均价列降序排序
    group_df.sort_values('均价', ascending=False, inplace=True)
    # 取Top10
    top10_df = group_df.head(10)
    # print(top10_df)
    # 为了横向柱状图展示,再从低到高排序一下
    top10_df.sort_values('均价', ascending=True, inplace=True)

    bar = (
        Bar(init_opts=opts.InitOpts(width="1500px"))
            .add_xaxis(top10_df['小区名称'].tolist())
            .add_yaxis("房价单价", top10_df['均价'].tolist(),
                       itemstyle_opts=opts.ItemStyleOpts(color=JsCode(top10_color_function)))
            .reversal_axis()
            .set_series_opts(label_opts=opts.LabelOpts(position="right"))
            .set_global_opts(title_opts=opts.TitleOpts(title="武汉各小区二手房房价TOP10"),
                             xaxis_opts=opts.AxisOpts(axislabel_opts={'interval': '0'}),
                             legend_opts=opts.LegendOpts(is_show=False))
    )

    # 判断是否单独显示,还是和其他图表一起显示
    if isembed:
        return bar.render_embed()
    else:
        return bar


def unit_price_analysis_by_district(df):
    # 获取要分析的数据列
    analysis_df = df.loc[:, ['区', '均价']]
    analysis_df.loc[:, '区'] = analysis_df.loc[:, '区'].astype('str')
    # 对小区名称分组,然后按照分组计算单价均价
    group = analysis_df.groupby('区', as_index=False)
    group_df = group.mean()
    group_df.loc[:, '均价'] = group_df.loc[:, '均价'].astype('int')
    # 按照均价列降序排序
    group_df.sort_values('均价', ascending=True, inplace=True)

    bar = (
        Bar(init_opts=opts.InitOpts(width="1500px"))
            .add_xaxis(group_df['区'].tolist())
            .add_yaxis("房价单价", group_df['均价'].tolist())
            .reversal_axis()
            .set_series_opts(label_opts=opts.LabelOpts(position="right"))
            .set_global_opts(title_opts=opts.TitleOpts(title="武汉各区域二手房房价排行榜"),
                             xaxis_opts=opts.AxisOpts(axislabel_opts={'interval': '0'}))
    )

    return bar.render_embed()


def add_sale_estate_col(row):
    return 0


def sale_estate_analysis_by_year(df, isembed):
    # 增加一列待售房屋数,初始值均为0
    df.loc[:, '待售房屋数'] = df.apply(add_sale_estate_col, axis=1)
    # 获取要用作数据分析的两列:建筑年份和待售房屋数
    analysis_df = df.loc[:, ['建筑年份', '待售房屋数']]
    # 因为建筑年份列有空值,先预处理一下
    analysis_df.dropna(inplace=True)
    # 按照建筑年份进行分组
    group = analysis_df.groupby('建筑年份', as_index=False)
    # 对每个分组进行统计计数
    group_df = group.count()
    group_df.loc[:, '待售房屋数'] = group_df.loc[:, '待售房屋数'].astype('int')

    pie = Pie(init_opts=opts.InitOpts(width='800px', height='600px', bg_color='white'))
    pie.add("pie", [list(z) for z in zip(group_df['建筑年份'].tolist(), group_df['待售房屋数'].tolist())]
            , radius=['40%', '60%']
            , center=['50%', '50%']
            , label_opts=opts.LabelOpts(
            position="outside",
            formatter="{b}:{c}:{d}%", )
            ).set_global_opts(
        title_opts=opts.TitleOpts(title='武汉二手房不同建筑年份的待售数量', pos_left='300', pos_top='20',
                                  title_textstyle_opts=opts.TextStyleOpts(color='black', font_size=16)),
        legend_opts=opts.LegendOpts(is_show=False))

    # 判断是否单独显示,还是和其他图表一起显示
    if isembed:
        return pie.render_embed()
    else:
        return pie


def unit_price_analysis_by_histogram(df, isembed):
    hist, bin_edges = np.histogram(df['均价'], bins=100)

    bar = (
        Bar()
            .add_xaxis([str(x) for x in bin_edges[:-1]])
            .add_yaxis('价格分布', [float(x) for x in hist], category_gap=0)
            .set_global_opts(
            title_opts=opts.TitleOpts(title='武汉二手房房价-单价分布-直方图', pos_left='center'),
            legend_opts=opts.LegendOpts(is_show=False)
        )
    )

    # 判断是否单独显示,还是和其他图表一起显示
    if isembed:
        return bar.render_embed()
    else:
        return bar


def total_price_analysis_by_histogram(df, isembed):
    hist, bin_edges = np.histogram(df['总价'], bins=100)

    bar = (
        Bar()
            .add_xaxis([str(x) for x in bin_edges[:-1]])
            .add_yaxis('价格分布', [float(x) for x in hist], category_gap=0)
            .set_global_opts(
            title_opts=opts.TitleOpts(title='武汉二手房房价-总价分布-直方图', pos_left='center'),
            legend_opts=opts.LegendOpts(is_show=False)
        )
    )

    # 判断是否单独显示,还是和其他图表一起显示
    if isembed:
        return bar.render_embed()
    else:
        return bar


def unit_price_analysis_by_scatter(df, isembed):
    df.sort_values('面积', ascending=True, inplace=True)

    square = df['面积'].to_list()
    unit_price = df['均价'].to_list()

    scatter = (
        Scatter()
            .add_xaxis(xaxis_data=square)
            .add_yaxis(
            series_name='',
            y_axis=unit_price,
            symbol_size=4,
            label_opts=opts.LabelOpts(is_show=False)
        )
            .set_global_opts(
            xaxis_opts=opts.AxisOpts(type_='value'),
            yaxis_opts=opts.AxisOpts(type_='value'),
            title_opts=opts.TitleOpts(title='武汉二手房面积-单价关系图', pos_left='center')
        )
    )

    # 判断是否单独显示,还是和其他图表一起显示
    if isembed:
        return scatter.render_embed()
    else:
        return scatter


def hot_word_analysis_by_wordcloud(df, isembed):
    txt = ''
    for index, row in df.iterrows():
        txt = txt + str(row['待售房屋']) + ';' + str(row['标签']) + '\n'

    word_weights = jieba.analyse.extract_tags(txt, topK=100, withWeight=True)

    word_cloud = (
        WordCloud()
            .add(series_name='高频词语', data_pair=word_weights, word_size_range=[10, 100])
            .set_global_opts(
            title_opts=opts.TitleOpts(
                title='武汉二手房销售热度词',
                title_textstyle_opts=opts.TextStyleOpts(font_size=23),
                pos_left='center'
            )
        )
    )

    # 判断是否单独显示,还是和其他图表一起显示
    if isembed:
        return word_cloud.render_embed()
    else:
        # png_name = 'hot_word_analysis_by_wordcloud.png'
        # make_snapshot(snapshot, word_cloud.render(), f"crawler/anjuke/static/{png_name}")
        # return png_name
        return word_cloud


def transform_name(row):
    district_name = row['区'].strip()
    if district_name == '江汉' or district_name == '江岸' or district_name == '硚口' or district_name == '汉阳' or district_name == '武昌' or district_name == '东西湖' or district_name == '洪山':
        district_name = district_name + '区'
    return district_name


def unit_price_analysis_by_map(df, isembed):
    data = []
    # 获取要分析的数据列
    analysis_df = df.loc[:, ['区', '均价']]
    # 按区列分组
    group_df = analysis_df.groupby('区', as_index=False)
    # 根据分组对均价列求平均值
    group_df = group_df.mean('均价')
    # print(group_df)
    # 将区的名字做一下转换,为下面的地图匹配做准备
    group_df['区'] = group_df.apply(transform_name, axis=1)
    group_df.loc[:, '均价'] = group_df.loc[:, '均价'].astype('int')
    # 将数据转换成map需要的数据格式
    for index, row in group_df.iterrows():
        district_array = [row['区'], row['均价']]
        data.append(district_array)

    map = (
        Map()
            .add('武汉各区域二手房房价', data, '武汉')
            .set_global_opts(
            title_opts=opts.TitleOpts(title='武汉各区域二手房房价地图', pos_left='center'),
            visualmap_opts=opts.VisualMapOpts(max_=26000),
            legend_opts=opts.LegendOpts(is_show=False)
        )
    )
    # 判断是否单独显示,还是和其他图表一起显示
    if isembed:
        return map.render_embed()
    else:
        # png_name = 'unit_price_analysis_by_map.png'
        # make_snapshot(snapshot, map.render(), f"crawler/anjuke/static/{png_name}")
        # return png_name
        return map


# if __name__ == '__main__':
#
#     # 读取csv
#     fpath = 'data/wuhanSecondHouse.csv'
#     df = pd.read_csv(fpath, header=[0], encoding='gbk')
#     df.drop_duplicates(keep='first', inplace=True)
#
#
#
#     # # 画图
#     # unit_price_analysis_by_square.render()
#     # unit_price_analysis_by_layout.render()
#     # unit_price_analysis_by_estate.render()
#     # sale_estate_analysis_by_year.render()
#     # unit_price_analysis_by_histogram.render()
#     # total_price_analysis_by_histogram.render()
#     # unit_price_analysis_by_scatter.render()
#     # hot_word_analysis_by_wordcloud.render()
#     # unit_price_analysis_by_map.render()
#
#     # 合并
#     page = Page(layout=Page.DraggablePageLayout)  # 可拖动布局
#
#     page.add(
#         unit_price_analysis_by_square,
#         unit_price_analysis_by_layout,
#         unit_price_analysis_by_estate,
#         sale_estate_analysis_by_year,
#         unit_price_analysis_by_histogram,
#         total_price_analysis_by_histogram,
#         unit_price_analysis_by_scatter,
#         hot_word_analysis_by_wordcloud,
#         unit_price_analysis_by_map
#     )
#
#     page.render("武汉二手房数据分析.html")

这里flask的app.py脚本为report_web.py,主要绑定一个url路由关系,映射到上面代码中的函数

"""
启动一个web网站,展示不同的分析数据图表
启动方法:进入/anjuke目录下,执行python report_web.py
"""

# -*- coding: UTF-8-*-

from flask import Flask, render_template
import drawChart as dbc
import pandas as pd

app = Flask(__name__)


# 读取csv
fpath = 'data/wuhanSecondHouse.csv'
df = pd.read_csv(fpath, header=[0], encoding='gbk')
df.drop_duplicates(keep='first', inplace=True)


@app.route("/unit_price_analysis_by_layout")
def bar_unit_price_analysis_by_layout():
    result = dbc.unit_price_analysis_by_layout(df, True)
    return result


@app.route("/unit_price_analysis_by_suqare")
def bar_unit_price_analysis_by_square():
    result = dbc.unit_price_analysis_by_square(df, True)
    return result


@app.route("/unit_price_analysis_by_estate")
def bar_unit_price_analysis_by_estate():
    str = dbc.unit_price_analysis_by_estate(df, True)
    return str


@app.route("/unit_price_analysis_by_district")
def bar_unit_price_analysis_by_district():
    str = dbc.unit_price_analysis_by_district(df)
    return str


@app.route("/pie_sale_estate_analysis_by_year")
def pie_sale_estate_analysis_by_year():
    str = dbc.sale_estate_analysis_by_year(df, True)
    return str


@app.route("/histogram_unit_price_analysis")
def histogram_unit_price_analysis():
    str = dbc.unit_price_analysis_by_histogram(df, True)
    return str


@app.route("/histogram_total_price_analysis")
def histogram_total_price_analysis():
    str = dbc.total_price_analysis_by_histogram(df, True)
    return str


@app.route("/scatter_unit_price_analysis")
def scatter_unit_price_analysis():
    str = dbc.unit_price_analysis_by_scatter(df, True)
    return str


@app.route("/word_cloud_hot_word_analysis")
def word_cloud_hot_word_analysis():
    str = dbc.hot_word_analysis_by_wordcloud(df, True)
    return str


@app.route("/map_unit_price_analysis")
def map_unit_price_analysis():
    str = dbc.unit_price_analysis_by_map(df, True)
    return str


@app.route("/show_all_analysis_chart")
def show_all_analysis_chart():
    # 获取按面积区间的单价分析数据
    unit_price_analysis_by_square = dbc.unit_price_analysis_by_square(df, False)
    # 获取按室区分的单价分析数据
    unit_price_analysis_by_layout = dbc.unit_price_analysis_by_layout(df, False)
    # 获取苏州各小区二手房房价TOP10
    unit_price_analysis_by_estate = dbc.unit_price_analysis_by_estate(df, False)
    # 获取不同建筑年份的待售房屋数
    sale_estate_analysis_by_year = dbc.sale_estate_analysis_by_year(df, False)
    # 苏州二手房房价-单价分布-直方图
    unit_price_analysis_by_histogram = dbc.unit_price_analysis_by_histogram(df, False)
    # 苏州二手房房价-总价分布-直方图
    total_price_analysis_by_histogram = dbc.total_price_analysis_by_histogram(df, False)
    # 苏州二手房面积-单价关系图
    unit_price_analysis_by_scatter = dbc.unit_price_analysis_by_scatter(df, False)
    # 苏州二手房销售热度词
    # hot_word_analysis_by_wordcloud_png_name = dbc.hot_word_analysis_by_wordcloud(df,False)
    hot_word_analysis_by_wordcloud = dbc.hot_word_analysis_by_wordcloud(df, False)
    # 苏州各区域二手房房价
    # unit_price_analysis_by_map_png_name = dbc.unit_price_analysis_by_map(df,False)
    unit_price_analysis_by_map = dbc.unit_price_analysis_by_map(df, False)

    return render_template("show_analysis_chart.html",
                           # dump_options():将经过get_options方法处理过的echarts配置项序列化为JSON格式(JsCode 生成的函数不带引号)
                           unit_price_analysis_by_square_option=unit_price_analysis_by_square.dump_options(),
                           unit_price_analysis_by_layout_option=unit_price_analysis_by_layout.dump_options(),
                           unit_price_analysis_by_estate_option=unit_price_analysis_by_estate.dump_options(),
                           sale_estate_analysis_by_year_option=sale_estate_analysis_by_year.dump_options(),
                           unit_price_analysis_by_histogram_option=unit_price_analysis_by_histogram.dump_options(),
                           total_price_analysis_by_histogram_option=total_price_analysis_by_histogram.dump_options(),
                           unit_price_analysis_by_scatter_option=unit_price_analysis_by_scatter.dump_options(),
                           hot_word_analysis_by_wordcloud_option=hot_word_analysis_by_wordcloud.dump_options(),
                           unit_price_analysis_by_map_option=unit_price_analysis_by_map.dump_options()
                           )


if __name__ == "__main__":
    app.run() 

static目录下的这三个静态资源文件文件,来源之前文章中生成的html文件:武汉二手房数据分析.html
在这里插入图片描述

https://assets.pyecharts.org/assets/v5/echarts.min.js
https://assets.pyecharts.org/assets/v5/echarts-wordcloud.min.js
https://assets.pyecharts.org/assets/v5/echarts.min.js
在浏览器中打开上述的网址,分别把内容复制到对应的文件中就行了,注意中文乱码,自己调整好即可

然后templates目录中的show_analysis_chart.html文件就好得到了,主要对网页进行渲染,与所依赖的static目录下的静态资源和flask的程序运行文件的联系起来,最终得到我们想要的网页可视化效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>武汉二手房数据分析报告</title>
    <script type="text/javascript" src="/static/echarts.min.js"></script>
    <script type="text/javascript" src="/static/echarts-wordcloud.min.js"></script>
    <script type="text/javascript" src="/static/hu2_bei3_wu3_han4.js"></script>
</head>
<body>
    <h1 align="center">武汉二手房数据分析报告</h1>
    <h2>1.武汉二手房按面积区间的房屋单价</h2>
    <div id="unit_price_analysis_by_square" style="width:900px; height:500px;"> </div>
    <script type="text/javascript">
        var unit_price_analysis_by_square_chart = echarts.init(document.getElementById('unit_price_analysis_by_square'));
        var option = {{ unit_price_analysis_by_square_option | safe }};
        unit_price_analysis_by_square_chart.setOption(option);
    </script>
    <h2>2.武汉二手房按户型的房屋单价</h2>
    <div id="unit_price_analysis_by_layout" style="width:900px; height:500px;"> </div>
    <script type="text/javascript">
        var unit_price_analysis_by_layout_chart = echarts.init(document.getElementById('unit_price_analysis_by_layout'));
        var option = {{ unit_price_analysis_by_layout_option | safe }};
        unit_price_analysis_by_layout_chart.setOption(option);
    </script>
     <h2>3.武汉各小区二手房房价TOP10</h2>
     <div id="unit_price_analysis_by_estate" style="width:1200px; height:500px;"> </div>
     <script type="text/javascript">
         var unit_price_analysis_by_estate_chart = echarts.init(document.getElementById('unit_price_analysis_by_estate'));
         var option = {{ unit_price_analysis_by_estate_option | safe }};
         unit_price_analysis_by_estate_chart.setOption(option);
     </script>
     <h2>4.武汉各区域二手房房价</h2>
     <!--<div><img src="/static/{{unit_price_analysis_by_map_png}}" style="width:1200px;height:600px"/></div>-->
     <div id="unit_price_analysis_by_map" style="width:900px; height:500px;"> </div>
     <script type="text/javascript">
         var unit_price_analysis_by_map_chart = echarts.init(document.getElementById('unit_price_analysis_by_map'));
         var option = {{ unit_price_analysis_by_map_option | safe }};
         unit_price_analysis_by_map_chart.setOption(option);
     </script>
      <h2>5.武汉二手房不同建筑年份的待售数量</h2>
      <div id="sale_estate_analysis_by_year" style="width:900px; height:500px;"> </div>
      <script type="text/javascript">
          var sale_estate_analysis_by_year_chart = echarts.init(document.getElementById('sale_estate_analysis_by_year'));
          var option = {{ sale_estate_analysis_by_year_option | safe }};
          sale_estate_analysis_by_year_chart.setOption(option);
      </script>
     <h2>6.武汉二手房房价-单价分布</h2>
     <div id="unit_price_analysis_by_histogram" style="width:900px; height:500px;"> </div>
     <script type="text/javascript">
         var unit_price_analysis_by_histogram_chart = echarts.init(document.getElementById('unit_price_analysis_by_histogram'));
         var option = {{ unit_price_analysis_by_histogram_option | safe }};
         unit_price_analysis_by_histogram_chart.setOption(option);
     </script>
    <h2>7.武汉二手房房价-总价分布</h2>
    <div id="total_price_analysis_by_histogram" style="width:900px; height:500px;"> </div>
    <script type="text/javascript">
        var total_price_analysis_by_histogram_chart = echarts.init(document.getElementById('total_price_analysis_by_histogram'));
        var option = {{ total_price_analysis_by_histogram_option | safe }};
        total_price_analysis_by_histogram_chart.setOption(option);
    </script>
    <h2>8.武汉二手房面积-单价关系</h2>
    <div id="unit_price_analysis_by_scatter" style="width:900px; height:500px;"> </div>
    <script type="text/javascript">
        var unit_price_analysis_by_scatter_chart = echarts.init(document.getElementById('unit_price_analysis_by_scatter'));
        var option = {{ unit_price_analysis_by_scatter_option | safe }};
        unit_price_analysis_by_scatter_chart.setOption(option);
    </script>
    <h2>9.武汉二手房销售热度词</h2>
    <!--<div><img src="/static/{{hot_word_analysis_by_wordcloud_png}}" style="width:1200px;height:600px"/></div>-->
    <div id="hot_word_analysis_by_wordcloud" class="chart-container" style="width:900px; height:500px;"></div>
    <script type="text/javascript">
        var hot_word_analysis_by_wordcloud_chart = echarts.init(document.getElementById('hot_word_analysis_by_wordcloud'), 'white', {renderer: 'canvas'});
        var option = {{ hot_word_analysis_by_wordcloud_option | safe }};
        hot_word_analysis_by_wordcloud_chart.setOption(option);
    </script>
</body>
</html>

四、web可视化效果

运行report_web.py后可在浏览器打开网址**http://127.0.0.1:5000/show_all_analysis_chart**查看结果
在这里插入图片描述
状态码全是200,说明成功,打开网址查看最终效果
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1141781.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

协同设计有哪些优势和作用?

组织结构越来越复杂&#xff0c;团队中的每个人都有独特的技能、经验和专业知识。我们如何才能让团队更好地合作&#xff1f;在这种情况下&#xff0c;协同设计应运而生。在本文中&#xff0c;将讨论什么是协同设计&#xff0c;如何帮助我们创造高质量的产品。 什么是协同设计…

RFNet模型数据集采集处理流程

文章目录 cityscapes数据集内容如何标注数据得到标签图片 cityscapes数据集内容 训练模型的时候下载了cityscapes里的disparity、gtFine和leftImg8bit。 共5000张图片。2975张训练&#xff0c;500张验证&#xff0c;1525test。每个目录下都有train、test和val的子目录,这些子…

vue3动态引入图片(:src)

vite 官方默认的配置&#xff0c;如果资源文件在assets文件夹打包后会把图片名加上 hash值&#xff0c;但是直接通过 :src"imgSrc"方式引入并不会在打包的时候解析&#xff0c;导致开发环境可以正常引入&#xff0c;打包后却不能显示的问题 实际上我们不希望资源文…

虚拟机构建部署单体项目及前后端分离项目

目录 一.部署单体项目 1.远程数据库 1.1远程连接数据库 1.2 新建数据库运行sql文件 2.部署项目到服务器中 3.启动服务器运行 二.部署前后端分离项目 1.远程数据库和部署到服务器 2.利用node环境启动前端项目 3.解决主机无法解析服务器localhost问题 方法一 ​编辑 方…

什么?Postman也能测WebSocket接口了?

01、WebSocket 简介 WebSocket是一种在单个TCP连接上进行全双工通信的协议。 WebSocket使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。在WebSocket API中&#xff0c;浏览器和服务器只需要完成一次握手&#xff0c;两者之间就直…

Python爬虫基础之Requests详解

目录 1. 简介2. 安装3. 发送请求4. 处理响应5. IP代理6. Cookie登录参考文献 原文地址&#xff1a;https://program-park.top/2023/10/27/reptile_4/ 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由…

IEEE Standard for SystemVerilog Chapter9. Processes

9.1 General 本条款描述了以下内容&#xff1a; --结构化程序&#xff08;initial程序、always程序、final程序&#xff09; --块语句&#xff08;begin-end顺序块&#xff0c;fork-join并行块&#xff09; --时序控制&#xff08;delays, events, wa…

【计算机网络】应用层——HTTP协议

目录 1.HTTP协议简介2.认识URL3.urlencode和urldecode4.HTTP请求协议和响应协议HTTP请求协议HTTP响应协议 5.HTTP请求方法6.HTTP状态码7.HTTP常见的Hander8.Cookie和Session 1.HTTP协议简介 HTTP&#xff08;Hyper Text Transfer Protocol&#xff09;协议又叫做超文本传输协议…

24 行为型模式-访问者模式

1 访问者模式介绍 访问者模式在实际开发中使用的非常少,因为它比较难以实现并且应用该模式肯能会导致代码的可读性变差,可维护性变差,在没有特别必要的情况下,不建议使用访问者模式。 2 访问者模式原理 3 访问者模式实现 我们以超市购物为例,假设超市中的三类商品: 水果,糖…

嵌入式软件工程师面试题——2025校招专题(四)

说明&#xff1a; 面试题来源于网络书籍&#xff0c;公司题目以及博主原创或修改&#xff08;题目大部分来源于各种公司&#xff09;&#xff1b;文中很多题目&#xff0c;或许大家直接编译器写完&#xff0c;1分钟就出结果了。但在这里博主希望每一个题目&#xff0c;大家都要…

python——requests模块

requests不是python的内置库&#xff0c;需要手动安装&#xff1a; pip install requests 一. 一个类型和六个属性 1.1 类型 requests访问url后返回的对象类型为requests.models.Response类型。 1.2 属性 下面是requests.models.Response类型对象的方法。 text&#xff1a;以…

【Javascript】json

目录 什么是json&#xff1f; 书写格式 json 序列化和反序列化 序列化 反序列化 什么是json&#xff1f; JSON(JavaScript Object Notation)是⼀种轻量级的数据交换格式&#xff0c;它基于JavaScript的⼀个⼦集&#xff0c;易于⼈的编写和阅读&#xff0c;也易于机器解析…

OSG开发笔记(二十九):OSG加载模型文件、加载3DMax三维型文件Demo

​ 若该文为原创文章&#xff0c;未经允许不得转载 本文章博客地址&#xff1a;https://blog.csdn.net/qq21497936/article/details/134064988 各位读者&#xff0c;知识无穷而人力有穷&#xff0c;要么改需求&#xff0c;要么找专业人士&#xff0c;要么自己研究 红胖子(红模…

班主任必get,超实用的成绩发布方式

分享给老师们一个超级实用的教程&#xff0c;看看如何使用各种代码和Excel实现学生自主查询成绩的功能吧&#xff01;不用再繁琐的手动操作&#xff0c;让学生和家长自己就能查到成绩&#xff01; 成绩查询系统是什么&#xff1f; 成绩查询系统是一种方便学生查询考试成绩的应…

Android 和 iOS APP 测试的那些区别

目前市面上主流的移动操作系统就是 Android 和 iOS 两种&#xff0c;移动端测试本身就跟 Web 应用测试有自己的专项测试&#xff0c;比如安装、卸载、升级、消息推送、网络类型测试、弱网测试、中断测试、兼容性测试等都是区别于 Web 应用需要关注的测试领域。 那么&#xff0…

办公用品经营配送小程序商城的作用是什么

对办公人员来说&#xff0c;办公设备是不可缺少的&#xff0c;对办公用品经营商家来说&#xff0c;市场生意很高很多&#xff0c;但想要获取却也不容易&#xff0c;线下方式难以拓展&#xff0c;线上无平台&#xff0c;入驻第三方也有诸多限制与不足&#xff0c;私域是商家们增…

关键词搜索1688商品数据接口(标题|主图|SKU|价格|优惠价|掌柜昵称|店铺链接|店铺所在地)

1688商品列表接口是一个用于获取1688网站上商品列表信息的接口。通过该接口&#xff0c;您可以获取到1688网站上不同类别的商品列表&#xff0c;包括商品的名称、价格、图片等信息。 要使用1688商品列表接口&#xff0c;您需要按照以下步骤进行操作&#xff1a; 登录1688网站…

Linux 磁盘挂载2(文件系统格式化、磁盘挂载、VFS虚拟化文件系统)

目录 Linux文件系统 文件系统类型 Linux如何保存文件 VFS虚拟文件系统 文件格式化命令 mkfs 格式化文件系统 磁盘挂载命令 mount 临时挂载命令 umount 卸载文件系统 vim /etc/fstab 永久挂载 Linux文件系统 Linux 磁盘挂载1&#xff08;硬盘分区&#xff09;_linux磁…

高效遮挡!一键隐藏Logo标志,让您的内容更自由!

亲爱的用户&#xff0c;您是否曾经因为在营销、宣传、推广等领域使用的图片或视频中&#xff0c;存在不合适的Logo标志而感到烦恼&#xff1f;现在&#xff0c;我们向您推荐一款高效的遮挡工具&#xff0c;让您轻松隐藏Logo标志&#xff0c;让您的内容更自由&#xff01; 第一…

面试题:为什么HashMap 使用的时候指定容量?

文章目录 前言正文为什么要指定容量&#xff1f; 前言 其实可以看到我写了这么久的博客&#xff0c;很少去写hashMap的东西。 为什么&#xff1f;因为这个东西感觉是java面试必备的&#xff0c;我感觉大家都看到腻了&#xff0c;所以一直没怎么去写hashMap相关的。 本篇内容&…