Django + Matplotlib:实现数据分析显示与下载为PDF或SVG

写作背景

首先,数据分析在当前的信息时代中扮演着重要的角色。随着数据量的增加和复杂性的提高,人们对于数据分析的需求也越来越高。

其次,笔者也确确实实曾经接到过一个这样的开发需求,甲方是一个医疗方面的科研团队,有相当大的一些关于癌症治疗方面的医疗数据,通过这些数据可以分析出很多东西,最重要的是将数据通过一些科学计算后转换为可视化的数据图,并且要根据用户的检索数据实时分析展示,并且可保存为pdf或svg格式的源文件,可提供后期印刷一类的二次修改使用;最终就选择了Django和Matplotlib这两个强大的库来实现数据分析的显示和下载功能。

本文将只会浅显的探讨如何使用Django和Matplotlib,并不会对数据分析方面的知识做过多的介绍!

环境搭建

这里我假设你已经会使用django,并且已经使用django搭建起了一个可运行的demo app。

Matplotlib的安装使用和其他的Python第三方包一致,只需要通过pip命令即可快速安装!

pip install matplotlib

代码示例

1、假如我们拥有一个如下代码所示的django 类视图

# demo/views.pyfrom django.shortcuts import render
from django.views.generic import Viewclass HomeView(View):"""HomeView类是一个继承自View的视图类,用于处理与主页相关的请求。Attributes:template_name (str): 展示主页所使用的模板名称。"""template_name = "demo/home.html"def get(self, request, *args, **kwargs):return render(request, self.template_name)

2、url如下所示

# 项目mysite的根urls.pyfrom django.urls import path
from. import viewsurlpatterns = [path('', views.HomeView.as_view(), name='index'),
]

3、demo/templates/demo目录下home.html代码如下

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body></body>
</html>

这只是一个空白的html页面,最后用来显示分析图!

那么,根据以上代码,我们可以通过django的runserver命令运行项目后看到该页面!

Matplotlib使用

1、在demo/views.py当中引入如下包

import base64
from io import BytesIO
from matplotlib.figure import Figurefrom django.http import FileResponse

代码解释:

import base64 是我们导入了Python的base64模块,该模块提供了对 Base64 编码格式的支持。Base64 是一种用于编码二进制数据的方式,它将每3个字节的数据编码为4个字符,因此会将数据的大小增加约33%。这种编码格式常用于在文本中进行二进制数据的表示,尤其是在需要将二进制数据通过电子邮件等文本通道进行传输的情况下。通过导入 base64 模块,我们可以使用该模块提供的函数和类来进行 Base64 编码和解码操作。

from io import BytesIO 这一行代码是在 Python 中导入 BytesIO 类。BytesIO 类是 Python 标准库 io 模块中的一个类,用于在内存中处理二进制数据流。

BytesIO 类实现了一个缓冲区,这个缓冲区可以像文件一样进行读写操作,但实际上是在内存中进行的。因此,它可以在内存中处理和操作二进制数据,而不需要将数据写入磁盘。

通过使用 BytesIO 类,我们可以将二进制数据存储在内存中,并像处理文件一样对其进行读取、写入和其他操作。这对于处理大量数据或在内存中执行文件操作更加高效和灵活。

from matplotlib.figure import Figure 是导入matplotlib 库中的 Figure 类,Figure 类是 matplotlib 库中的一个核心类,用于创建一个图形窗口(figure window)。这个窗口可以包含各种图形元素,如坐标轴(axes)、曲线(lines)、文本(text)等。

通过导入 Figure 类,我们可以创建一个空的图形窗口,并在其中添加各种图形元素。这对于自定义图形的外观和布局非常有用。

from django.http import FileResponse是导入django为我们提供的一个响应对象,关于其作用django的官网对其有详细说明,如下所示:

2、实现在页面中显示分析图的需求

首先,我们在HomeView类中新增一个get_fig的方法,让其生成一个分析图对象:

class HomeView(View):...def get_fig(self):"""获取一个图形和轴对象返回:fig (matplotlib.figure.Figure): 图形对象ax (matplotlib.axes.Axes): 轴对象"""fig = Figure(figsize=(5, 5))  # 创建一个大小为 5x5 的图形对象ax = fig.subplots()  # 在图形对象上创建一个子图对象ax.plot([1, 2, 3, 4])  # 在轴对象上绘制一条线# 标题fig.suptitle("Hello world")  # 设置图形的标题# 坐标轴ax.set_ylabel("Y zhou", fontdict={"size": 16, "color": "red", "weight": "bold", "family": "serif"})  # 设置轴对象的 y 轴标签ax.set_xlabel("X zhou")  # 设置轴对象的 x 轴标签return fig, ax  # 返回图形对象和轴对象

有了该图形对象之后,我们就可以用base64包将该图形对象在内存中转换为png格式的字节流,为此我们再在该视图类下新增一个img_base64_to_file的方法,让它接收一个图形对象fig作为参数!

class HomeView(View):...def img_base64_to_file(self, fig):"""将图像保存为base64编码的文件参数:fig:要保存的图像对象返回值:img:包含base64编码图像的HTML标签"""buf = BytesIO()  # 创建字节流用于保存图像fig.savefig(buf, format="png")  # 将图像保存为png格式的字节流data = base64.b64encode(buf.getbuffer()).decode("ascii")  # 将字节流转换为base64编码的字符串img = f"<img src='data:image/png;base64,{data}'/>"  # 构建包含base64编码图像的HTML标签return img  # 返回HTML标签

做完以上两步之后,其实只需要将img_base64_to_file方法的返回值传递到get请求的上下文当中,在django的模版中通过模版过滤器safe渲染即可!其他动态筛选逻辑以及其他操作即可通过django的相关功能去实现!代码如下:

class HomeView(View):...def get(self, request, *args, **kwargs):fig, ax = self.get_fig()img = self.img_base64_to_file(fig) return render(request, self.template_name, {"img": img})

静态html模版中如下

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>{{ img|safe }}
</body>
</html>

最终渲染图

3、实现将分析图保存为pdf或svg格式

要实现该需求其实也非常简单,只需要在该视图类中新增一个post的请求,使用django的FileResponse将数据流保存到本地即可,其中需要关注的只是fig图形对象中的savefig方法的format参数的变化,也就是保存文件的格式,这个函数本身就是支持导出pdf和svg格式的!代码如下:

class HomeView(View):...def download_response(self, fig, filename:str):"""将给定的图形对象 fig 保存为 pdf 格式的文件并下载。参数:self (object): 类实例对象fig (matplotlib.figure.Figure): 绘制好的图形对象filename (str): 保存的文件名,包含扩展名返回值:FileResponse: 用于文件下载的响应对象"""buf = BytesIO()fig.savefig(buf, format="pdf")buf.seek(0)return FileResponse(buf, as_attachment=True, filename=f"{filename}.pdf")def post(self, request, *args, **kwargs):fig,ax = self.get_fig()return self.download_response(fig, "demo")

在html模版中通过post的表单请求即可下载,代码如下:

<body>{{ img|safe }}<form action="" method="post">{% csrf_token %}submit: <input type="submit" value="下载"></form>
</body>

最终,通过点击下载按钮,发起一个post请求就实现了下载到本地的功能,当然你想动态控制下载格式的话,还可以通过django的表单系统开放给用户,让用户自由选择所需要的下载格式,需要注意的是format参数要和文件后缀格式保持一致!


作者开源商城项目,欢迎大家fork学习,同步开发教程持续更新

开源地址:https://gitee.com/xingfugz/bayke-shop

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaSE基础50题:10. 计算1/1-1/2+1/3-……+1/99-1/100的值(两种方法)

概述 计算1/1 - 1/2 1/3 - …… 1/99 - 1/100的值。 当分母为偶数时&#xff0c;符号是负的&#xff0c;放分母为奇数时&#xff0c;符号是负的。 方法一 用 flg 做了一个正负交替 【代码】 public static double func() {double sum 0;int flg 1; //设置正负号的for (i…

LeetCode Hot100 46.全排列

题目&#xff1a; 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 代码&#xff1a; class Solution {private int[] nums;private List<Integer> path; // 记录路径上的数&#xff0c;已选数字private boo…

Linux学习笔记之八(进程间的共享内存)

Linux 1、引言2、实现共享内存2.1、创建一个共享内存2.2、将共享内存链接到进程空间2.3、断开与共享内存的链接2.4、对共享内存进行后续操作 3、应用实例 1、引言 在之前一篇文章Linux学习笔记之六&#xff08;进程之间的管道通信和信号处理&#xff09;中我讲了进程间可以通过…

Unity中Batching优化的GPU实例化(2)

文章目录 前言一、GPU实例化的Shader准备步骤1、在Pass中声明实例化需要的变体2、UNITY_VERTEX_INPUT_INSTANCE_ID 在顶点着色器的输入(appdata)和输出(v2f可选)中添加(uint instanceID : SV_InstanceID). 前言 在上篇文章中&#xff0c;我们做了一些GPU实例化的前置准备&…

使用arcpy移除遥感影像云层

先讲思路&#xff0c;然后上代码&#xff1a; 去除云层 思路1&#xff1a; 如果同一地理区域的多个图像&#xff0c;其中一些部分有丰富的云&#xff0c;而另一些部分没有云&#xff0c;则可以将它们组合起来&#xff0c;以便无云的部分替代多云的部分。这种方法很简单&…

[原创][6]探究C#多线程开发细节-“ConcurrentDictionary<T,T>解决多线程的无顺序性的问题“

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XX QQ联系: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、D…

Data Mining数据挖掘—2. Classification分类

3. Classification Given a collection of records (training set) – each record contains a set of attributes – one of the attributes is the class (label) that should be predicted Find a model for class attribute as a function of the values of other attribu…

从传统到胜利:广汽集团汽车产业创新之旅

置身于汽车行业百年未有之大变局&#xff0c;作为传统车企中的排头兵&#xff0c;广汽创新可圈可点&#xff0c;广汽近年来取得了骄人业绩&#xff0c;不论是整体产销规模&#xff0c;还是新能源汽车产业化、新技术领域开拓等&#xff0c;都呈现节节攀升的局面。本文奖从产业变…

基于ssm少儿编程管理系统源码和论文

idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 环境&#xff1a; jdk8 tomcat8.5 开发技术 ssm 基于ssm少儿编程管理系统源码和论文744 摘要 网络的广泛应用给生活带来了十分的便利。所以把少儿编程管理系统与现在网络相结合&#xff0c;利用java技术建设…

使用Caliper对Fabric地basic链码进行性能测试

如果你需要对fabric网络中地合约进行吞吐量、延迟等性能进行评估&#xff0c;可以使用Caliper来实现&#xff0c;会返回给你一份网页版的直观测试报告。下面是对test-network网络地basic链码地测试过程。 目录 1. 建立caliper-workspace文件夹2. 安装npm等3. calipe安装4. 创建…

6-4 是否二叉搜索树 分数 20

bool IsBST(BinTree T) {//空树 or 只有一个结点if (T NULL || (T->Left NULL) && (T->Right NULL))return true;BinTree cur NULL;cur T->Left;if (cur ! NULL){while (cur->Right)cur cur->Right;if (cur->Data > T->Data)return fals…

vue 商品列表案例

my-tag 标签组件的封装 1. 创建组件 - 初始化 2. 实现功能 (1) 双击显示&#xff0c;并且自动聚焦 v-if v-else dbclick 操作 isEdit 自动聚焦&#xff1a; 1. $nextTick > $refs 获取到dom&#xff0c;进行focus获取焦点 2. 封装v-focus指令 (2) 失去焦点&#xff0c;隐藏…