综合项目:Flask 实现数据可视化

效果:

Flask介绍

Flask是一个用Python编写的轻量级Web应用框架。它被设计为易于使用,同时提供强大的功能,以便开发者可以快速地开发Web应用程序。以下是Flask的一些关键特点:

  • 轻量级:Flask没有默认的数据库、表单验证或任何其他特定的工具。它提供了一个核心功能,开发者可以根据自己的需要选择添加其他组件。
  • 可扩展性:Flask通过扩展来提供额外的功能,这些扩展可以轻松集成到你的应用程序中。
  • 灵活性:Flask允许开发者以他们喜欢的方式构建应用程序,无论是使用对象关系映射(ORM)还是简单的SQL表达式。
  • 开发服务器和调试器:Flask提供了一个内置的开发服务器和一个调试器,这使得开发和测试应用程序变得非常容易。

安装Flask

可以通过 pip 来安装 Flask。打开你的命令行工具(在 Windows 上是命令提示符或 PowerShell,在 macOS 或 Linux 上是终端),然后输入以下命令:

pip install Flask

这将从 Python 包索引(PyPI)下载并安装 Flask。

验证安装,为了确保 Flask 已正确安装,你可以创建一个简单的 Python 脚本来测试 Flask 是否可以被导入。创建一个名为 test_flask.py 的文件,并写入以下内容:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

if __name__ == '__main__':
    app.run(debug=True)

如果 Flask 已正确安装,这将启动一个开发服务器,你可以通过浏览器访问 http://127.0.0.1:5000/ 来查看 “Hello, World!” 的消息。

Flask的目录结构

/22306大数据可视化
    /venv         # 虚拟环境文件夹
    /templates   # 存放 HTML 模板文件
        - index.html
    /static      # 存放静态文件,如 CSS, JavaScript, 图片等
        /css
        /js
        /img
    app.py        # 运行 Flask 应用的脚本 

获取网页模板

初始的网页必然是简陋的,要变成精美的页面,要么自己编写html+css+javascript,要么套用模板。
见网站:https://sc.chinaz.com/moban/
https://sc.chinaz.com/moban/200226033740.htm
下载后内容包括:
alt text
assets放在static文件夹下
index.html 放在temlates下。

使得flask程序,加载模板网页

from flask import Flask
from flask import render_template
app = Flask(__name__)

@app.route('/')
def home():
   
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=True)

在程序套用模板后,程序运行时打开的为存放在temlates下的index.html。
同时,可以将程序运行的结果与网页进行联动,参考以下案例:

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def home():
    my_message = "Hello, World!"
    return render_template('index.html', message=my_message)

if __name__ == '__main__':
    app.run(debug=True)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试网页</title>
</head>
<body>
    <h1>{{ message }}</h1>
</body>
</html>

我们根据需要对网页进行简化,对index.html 进行修改。
修改后文件如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta content="width=device-width, initial-scale=1.0" name="viewport">

  <title>Home</title>
  <meta content="" name="descriptison">
  <meta content="" name="keywords">

  <!-- Favicons -->
  <link href="static/assets/img/favicon.png" rel="icon">
  <link href="static/assets/img/apple-touch-icon.png" rel="apple-touch-icon">

  <!-- Google Fonts -->
  <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i|Raleway:300,300i,400,400i,600,600i,700,700i,900" rel="stylesheet">

  <!-- Vendor CSS Files -->
  <link href="static/assets/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
  <link href="static/assets/vendor/icofont/icofont.min.css" rel="stylesheet">
  <link href="static/assets/vendor/boxicons/css/boxicons.min.css" rel="stylesheet">
  <link href="static/assets/vendor/animate.css/animate.min.css" rel="stylesheet">
  <link href="static/assets/vendor/venobox/venobox.css" rel="stylesheet">
  <link href="static/assets/vendor/aos/aos.css" rel="stylesheet">

  <!-- Template Main CSS File -->
  <link href="static/assets/css/style.css" rel="stylesheet">

</head>

<body>

  


  <!-- ======= Hero Section ======= -->
  <section id="hero">
    <div class="hero-container">
      <div id="heroCarousel" class="carousel slide carousel-fade" data-ride="carousel">

        <ol class="carousel-indicators" id="hero-carousel-indicators"></ol>

        <div class="carousel-inner" role="listbox">

          <!-- Slide 1 -->
          <div class="carousel-item active" style="background-image: url('static/assets/img/slide/slide-1.png');">
            <div class="carousel-container">
              <div class="carousel-content container">
                <h2 class="animated fadeInDown">B站UP主:小约翰可汗</h2>
                <p class="animated fadeInUp">bilibili个人认证:2023百大UP主、2023年度商业影响力、2022年度最高人气奖UP主</p>
                <a href="https://space.bilibili.com/23947287" class="btn-get-started animated fadeInUp scrollto">了解更多</a>
              </div>
            </div>
          </div>

          <!-- Slide 2 -->
          <div class="carousel-item" style="background-image: url('static/assets/img/slide/slide-2.jpg');">
            <div class="carousel-container">
              <div class="carousel-content container">
                <h2 class="animated fadeInDown">制作者:22306班</h2>
                <p class="animated fadeInUp">大数据技术应用专业,数据分析课程项目展示。B站知名Up主投稿数据分析项目。</p>
                <a href="#about" class="btn-get-started animated fadeInUp scrollto">Read More</a>
              </div>
            </div>
          </div>

          

        </div>

        <a class="carousel-control-prev" href="#heroCarousel" role="button" data-slide="prev">
          <span class="carousel-control-prev-icon icofont-rounded-left" aria-hidden="true"></span>
          <span class="sr-only">Previous</span>
        </a>
        <a class="carousel-control-next" href="#heroCarousel" role="button" data-slide="next">
          <span class="carousel-control-next-icon icofont-rounded-right" aria-hidden="true"></span>
          <span class="sr-only">Next</span>
        </a>

      </div>
    </div>
  </section><!-- End Hero -->

  <main id="main">


  
    <!-- ======= Counts Section ======= -->
    <section class="counts section-bg">
      <div class="section-title">
        <h2>UP主总体数据</h2>
      </div>
      <div class="container">

        <div class="row">

          <div class="col-lg-3 col-md-6 text-center" data-aos="fade-up">
            <div class="count-box">
              <img src="static/assets/img/播放.png" style="width: 64px; height: 64px;">
              <span data-toggle="counter-up"> {{ total_plays }}</span>
              <p>播放(万)</p>
            </div>
          </div>

          <div class="col-lg-3 col-md-6 text-center" data-aos="fade-up" data-aos-delay="200">
            <div class="count-box">
              <img src="static/assets/img/点赞.png" style="width: 64px; height: 64px;">
              <span data-toggle="counter-up"> {{ total_likes }}</span>
              <p>点赞(万)</p>
            </div>
          </div>

          <div class="col-lg-3 col-md-6 text-center" data-aos="fade-up" data-aos-delay="400">
            <div class="count-box">
              <img src="static/assets/img/投币.png" style="width: 64px; height: 64px;">
              <span data-toggle="counter-up">{{ total_coins }}</span>
              <p>投币(万)</p>
            </div>
          </div>

          <div class="col-lg-3 col-md-6 text-center" data-aos="fade-up" data-aos-delay="600">
            <div class="count-box">
              <img src="static/assets/img/转发.png" style="width: 64px; height: 64px;">
              <span data-toggle="counter-up"> {{ total_share }}</span>
              <p>转发(万)</p>
            </div>
          </div>

        </div>

      </div>
    </section><!-- End Counts Section -->
   
    <!-- ======= About Us Section ======= -->
    <section id="about" class="about">
      <div class="container">
        <div class="section-title">
          <h2>UP主选题词云</h2>
        </div>
        <div class="row no-gutters">
            <img src="static/assets/img/Figure_1.png" style=" width: 100%;">
    
        </div>

      </div>
    </section><!-- End About Us Section -->
    <section id="about" class="about">
      <div class="container">
        <div class="section-title">
          <h2>视频点赞投币比</h2>
        </div>
        <div class="row no-gutters">
         
            <img src="static/assets/img/Figure_2.png" style=" width: 100%;">
      
        </div>

      </div>
    </section><!-- End About Us Section -->
    <section id="about" class="about">
      <div class="container">
        <div class="section-title">
          <h2>标签播放统计</h2>
        </div>
        <div class="row no-gutters">
            <img src="static/assets/img/Figure_3.png" style=" width: 100%;">
 
        </div>

      </div>
    </section><!-- End About Us Section -->
    <section id="about" class="about">
      <div class="container">
        <div class="section-title">
          <h2>视频点赞投币比</h2>
        </div>
        <div class="row no-gutters">
         
            <img src="static/assets/img/Figure_2.png" style=" width: 100%;">
      
        </div>

      </div>
    </section><!-- End About Us Section -->
    <section id="about" class="about">
      <div class="container">
        <div class="section-title">
          <h2>24小时粉丝数量变化</h2>
        </div>
        <div class="row no-gutters">
            <img src="static/assets/img/Figure_4.png" style=" width: 100%;">
 
        </div>

      </div>
    </section><!-- End About Us Section -->
    
  </main><!-- End #main -->

  <!-- ======= Footer ======= -->
  <footer id="footer">
   

    <div class="container">
      <div class="copyright">Copyright &copy; 2020.Company name All rights reserved.<a target="_blank" href="http://sc.chinaz.com/moban/">&#x7F51;&#x9875;&#x6A21;&#x677F;</a></div>
      <div class="credits"></div>
    </div>
  </footer><!-- End Footer -->

  <a href="#" class="back-to-top"><i class="icofont-simple-up"></i></a>

  <!-- Vendor JS Files -->
  <script src="static/assets/vendor/jquery/jquery.min.js"></script>
  <script src="static/assets/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
  <script src="static/assets/vendor/jquery.easing/jquery.easing.min.js"></script>
  <script src="static/assets/vendor/php-email-form/validate.js"></script>
  <script src="static/assets/vendor/jquery-sticky/jquery.sticky.js"></script>
  <script src="static/assets/vendor/venobox/venobox.min.js"></script>
  <script src="static/assets/vendor/waypoints/jquery.waypoints.min.js"></script>
  <script src="static/assets/vendor/counterup/counterup.min.js"></script>
  <script src="static/assets/vendor/isotope-layout/isotope.pkgd.min.js"></script>
  <script src="static/assets/vendor/aos/aos.js"></script>

  <!-- Template Main JS File -->
  <script src="static/assets/js/main.js"></script>

</body>

</html>

调整之前的程序代码

调整之前的程序代码,使得程序的结果图片,能正确的存放到指定位置。
例如:

plt.savefig('static\\assets\\img\\Figure_1.png')

调整app.py,能动态获取UP主视频播放基本情况

from flask import Flask
from flask import render_template
import pandas as pd
app = Flask(__name__)
@app.route('/')
def hello_world():
    df = pd.read_csv('小约翰可汗.csv')
    df=df.dropna()

    total_plays = df['播放数'].sum()
    total_likes = df['点赞数'].sum()
    total_coins = df['投币数'].sum()
    total_share = df['转发数'].sum()
    # 转换为以万为单位,并保留一位小数
    total_plays_in_ten_thousands = round(total_plays / 10000, 1)
    total_likes_in_ten_thousands = round(total_likes / 10000, 1)
    total_coins_in_ten_thousands = round(total_coins / 10000, 1)
    total_share_in_ten_thousands = round(total_share / 10000, 1)


    return render_template('index.html',total_plays=total_plays_in_ten_thousands,total_likes=total_likes_in_ten_thousands,total_coins=total_coins_in_ten_thousands,total_share=total_share_in_ten_thousands)

if __name__=='__main__':
    app.run(debug=True)