下面是一个基于 Django 和 Matplotlib 库的数据可视化应用示例。
首先,我们需要安装 Matplotlib 库:
pip install matplotlib
然后,在 Django 项目中创建一个名为 graph 的应用程序:
python manage.py startapp graph
接下来,我们在 graph/views.py 文件中编写视图函数,该函数将读取数据库中的数据,并使用 Matplotlib 库生成一个折线图:
# graph/views.py
from django.shortcuts import render
import matplotlib.pyplot as plt
from .models import Data
def show_graph(request):
data = Data.objects.all()
x = [d.date for d in data]
y = [d.value for d in data]
plt.plot(x, y)
plt.title('Data Visualization')
plt.xlabel('Date')
plt.ylabel('Value')
plt.grid(True)
plt.savefig('media/graph.png')
return render(request, 'graph.html', {'graph_path': '/media/graph.png'})
在上述代码中,我们首先导入了 render 函数、matplotlib.pyplot 库和 Data 模型类。然后,我们查询数据库中的所有数据,并将其分别存储在 x 和 y 列表中。接着,我们使用 Matplotlib 库绘制折线图,并设置图表的标题、坐标轴标签和网格线。最后,我们将图表保存到 media 目录下,并将图表路径作为变量传递给模板文件。
接下来,我们在 graph/templates/graph.html 文件中编写 HTML 模板代码,该模板将显示图表并提供一个按钮来刷新数据:
<!-- graph/templates/graph.html -->
<!DOCTYPE html>
<html>
<head>
<title>Graph</title>
</head>
<body>
<img src="{{ graph_path }}" alt="Graph">
<form method="post" action="{% url 'show_graph' %}">
{% csrf_token %}
<input type="submit" value="Refresh Data">
</form>
</body>
</html>
在上述代码中,我们使用 Django 模板语言引用了视图函数传递的图表路径变量,并在页面上显示了一个 <img> 元素。此外,我们还添加了一个表单元素,当用户点击“刷新数据”按钮时,将触发 show_graph 视图函数。
最后,我们需要在 urls.py 文件中添加一个 URL 映射来将请求路由到 show_graph 视图函数:
# urls.py
from django.urls import path
from .views import show_graph
urlpatterns = [
path('graph/', show_graph, name='show_graph'),
]
到此为止,我们已经完成了基于 Django 和 Matplotlib 的数据可视化应用程序。当用户访问 /graph/ 页面时,将会显示一个折线图,并提供一个按钮来刷新数据。您可以将此示例代码作为起点,根据需求添加更多功能和交互效果。
-----------------后续--------------
为了让这个样例更加完整,我们还可以添加以下功能:
- 数据库模型类:在 graph/models.py 文件中定义一个数据模型类,用于表示需要可视化的数据。例如,我们可以创建一个名为 Data 的模型,包含日期和值两个字段:
# graph/models.py
from django.db import models
class Data(models.Model):
date = models.DateField()
value = models.IntegerField()
def __str__(self):
return f'{self.date}: {self.value}'
- 数据导入功能:在 graph/views.py 文件中添加一个视图函数,用于从 CSV 文件中导入数据并存储到数据库中。例如,我们可以编写一个名为 import_data 的视图函数,允许用户上传 CSV 文件,读取其中的数据,并将其保存到 Data 模型中:
# graph/views.py
import csv
def import_data(request):
if request.method == 'POST':
csv_file = request.FILES['csv_file']
reader = csv.DictReader(csv_file)
for row in reader:
date = row['date']
value = row['value']
Data.objects.create(date=date, value=value)
return redirect('show_graph')
return render(request, 'import_data.html')
在上述代码中,我们首先检查请求方法是否为 POST,如果是,则获取上传的 CSV 文件对象,并使用 Python 标准库中的 csv.DictReader 类来读取其中的数据。然后,我们循环遍历每一行数据,将日期和值分别存储到 date 和 value 变量中,并使用 Data.objects.create 方法创建一个新的数据对象并保存到数据库中。最后,我们重定向到 show_graph 视图函数。
- 数据过滤功能:在 graph/views.py 文件中添加一个视图函数,用于按日期范围过滤数据。例如,我们可以编写一个名为 filter_data 的视图函数,允许用户输入起始日期和截止日期,然后显示该范围内的数据:
# graph/views.py
from django.db.models import Q
from datetime import datetime
def filter_data(request):
if request.method == 'POST':
start_date = request.POST.get('start_date')
end_date = request.POST.get('end_date')
data = Data.objects.filter(Q(date__gte=start_date) & Q(date__lte=end_date))
x = [d.date for d in data]
y = [d.value for d in data]
plt.plot(x, y)
plt.title('Data Visualization')
plt.xlabel('Date')
plt.ylabel('Value')
plt.grid(True)
plt.savefig('media/graph.png')
return render(request, 'graph.html', {'graph_path': '/media/graph.png'})
return render(request, 'filter_data.html')
在上述代码中,我们首先检查请求方法是否为 POST,如果是,则获取用户输入的起始日期和截止日期,并使用 Django ORM 中的 Q 对象来构建一个查询条件。然后,我们查询符合条件的数据,并将其分别存储在 x 和 y 列表中。接着,我们使用 Matplotlib 库绘制折线图,并将其保存到 media 目录下,最后返回 graph.html 模板并传递图表路径变量。如果请求方法不是 POST,则返回一个 HTML 表单,允许用户输入起始日期和截止日期。
<!-- graph/templates/filter_data.html -->
<!DOCTYPE html>
<html>
<head>
<title>Filter Data</title>
</head>
<body>
<h1>Filter Data</h1>
<form method="post" action="{% url 'filter_data' %}">
{% csrf_token %}
<label for="start_date">Start Date:</label>
<input type="date" id="start_date" name="start_date"><br><br>
<label for="end_date">End Date:</label>
<input type="date" id="end_date" name="end_date"><br><br>
<button type="submit">Submit</button>
</form>
</body>
</html>
在上述代码中,我们首先定义一个表单元素,并将其提交到名为 filter_data 的视图函数。然后,在表单中添加两个输入框,分别用于输入起始日期和截止日期,并使用 <label> 元素为每个输入框添加标签。最后,我们添加一个提交按钮,用于触发表单提交操作。