Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Mastering Flask Web and API Development

You're reading from   Mastering Flask Web and API Development Build and deploy production-ready Flask apps seamlessly across web, APIs, and mobile platforms

Arrow left icon
Product type Paperback
Published in Aug 2024
Publisher Packt
ISBN-13 9781837633227
Length 494 pages
Edition 1st Edition
Languages
Tools
Concepts
Arrow right icon
Author (1):
Arrow left icon
Sherwin John C. Tragura Sherwin John C. Tragura
Author Profile Icon Sherwin John C. Tragura
Sherwin John C. Tragura
Arrow right icon
View More author details
Toc

Table of Contents (18) Chapters Close

Preface 1. Part 1:Learning the Flask 3.x Framework
2. Chapter 1: A Deep Dive into the Flask Framework FREE CHAPTER 3. Chapter 2: Adding Advanced Core Features 4. Chapter 3: Creating REST Web Services 5. Chapter 4: Utilizing Flask Extensions 6. Part 2:Building Advanced Flask 3.x Applications
7. Chapter 5: Building Asynchronous Transactions 8. Chapter 6: Developing Computational and Scientific Applications 9. Chapter 7: Using Non-Relational Data Storage 10. Chapter 8: Building Workflows with Flask 11. Chapter 9: Securing Flask Applications 12. Part 3:Testing, Deploying, and Building Enterprise-Grade Applications
13. Chapter 10: Creating Test Cases for Flask 14. Chapter 11: Deploying Flask Applications 15. Chapter 12: Integrating Flask with Other Tools and Frameworks 16. Index 17. Other Books You May Enjoy

Building graphical charts with frontend libraries

Most developers prefer rendering graphs and charts using frontend libraries rather than matplotlib, which requires complex Python coding to refine presentation and lacks UI-related features such as responsiveness, adaptability, and user interaction. This section will highlight the Chart.js, Bokeh, and Plotly libraries, which are all popular libraries with varying strengths and weaknesses as external tools for visualization.

Let’s begin with Chart.js.

Plotting with Chart.js

The most common and popular charting library used in many visualization applications is Chart.js. It is 100% JS, is lightweight, is easy to use, and has a straightforward syntax for designing graphs and charts. The following is the Chart.js implementation that displays the mean HPI values of certain countries:

<!DOCTYPE html>
<html lang="en">
<head>
  … … … … … …
  … … … … … …
  <script src='https://cdn.jsdelivr.net/npm/chart.js'></script>
</head>
<body>
    <h1>{{ title }}</h1>
    <form action="{{request.path}}" method="POST" enctype="multipart/form-data">
      Upload XLSX file:
      <input type="file" name="data_file"/><br/>
      <input type="submit" value="Upload File"/>
  </form><br/>
  <canvas id="linechart" width="300" height="100"></canvas>
</body>
<script>
  var linechart = document.getElementById("linechart");
  Chart.defaults.font.family = "Courier";
  Chart.defaults.font.size = 14;
  Chart.defaults.color = "black";

Chart.js is available in three sources:

Based on the HTML script, our implementation opted for the CDN source.

After referencing Chart.js, create a <canvas> tag with the width and height that fits your plot. Then, create a Chart() instance with the node or 2D context of <canvas> and some configuration options. Moreover, set new and appropriate values to global default properties such as the font name, font size, and font color:

  new Chart(linechart,{
      type: 'line',
      options: {
          scales: {
            y: {
              beginAtZero: true,
              title: {
                display: true,
                text: 'Mean HPI'
              }
            },
            x: {
              offset: true,
              title: {
                display: true,
                text: 'Countries with HPI'
              }
            }
          }
      },
      data: {
          borderWidth: ,
          labels : [
            {% for item in labels %}
              "{{ item }}",
            {% endfor %}
          ],

The data property provides the x-axis labels, data points, and connecting lines. Its datasets sub-property contains the look-and-feel details of the plots with the actual data. Both the label and data lists are context data supplied by its view function:

          datasets: [{
              fill : true,
              barPercentage: 0.5,
              barThickness: 20,
              maxBarThickness: 70,
              borderWidth : 1,
              minBarLength: 5,
              backgroundColor: "rgba(230,112,16,0.88)",
              borderColor : "rgba(38,22,6,0.88)",
              label: 'Mean HPI values',
              data : [
                {% for item in values %}
                  "{{ item }}",
                  {% endfor %}
              ]
            }]
        }
      });
</script>
</html>

Now, Chart.js can also build multiple line graphs, varieties of bar graphs, pie charts, and doughnuts, all using the same setup as the given line graph. Running the view function with the given Chart.js script will render a line graph, as indicated in Figure 6.17.

Figure 6.17 – A line graph for HPI values per country

Figure 6.17 – A line graph for HPI values per country

Chart.js supports responsive web design and interactive results, such as the given line graph that provides us with some information during mouse-over on every line dot. Despite its popularity, Chart.js still utilizes HTML canvas, which cannot render efficiently large and complex graphs. Also, it lacks other interactive utilities present in Bokeh and Plotly.

Let us now create graphs using a module friendlier to Python, Plotly.

Creating graphs with Plotly

Plotly is also a JS-based library that can render interactive charts and graphs. It is a popular library for various statistical and mathematical projects that require interactive data visualization and 3D graphics effects and can seamlessly plot DataFrame datasets.

To utilize its classes and methods for plotting graphs, install the plotly module through the pip command:

pip install plotly

The following view function uses Plotly to create a grouped bar graph about the price and bedroom preferences of buyers categorized according to their furnishing status preference:

import json
import plotly
import plotly.express as px
@rendition_bp.route("/plotly/csv/bedprice", methods = ['GET', 'POST'])
async def create_plotly_stacked_bar():
    if request.method == 'GET':
        graphJSON = '{}'
    else:
        … … … … … …
        try:
            df_csv = read_csv(uploaded_file)
            fig = px.bar(df_csv, x='Bedrooms', y='Price', color='FurnishingStatus', barmode='group')
            graphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
        except:
            raise FileSavingException()
    return render_template('plotly.html', graphJSON=graphJSON, title="Stacked Bar Graph of Bedroom vs Price per Furnishing Status")

Plotly has a plotly.express module, which provides several plotting utilities that can set up build graphs with DataFrame as input, similar to matplotlib’s methods. In the given create_plotly_stacked_bar() view function, the goal is to create a grouped bar chart using the bar() method from the plotly.express module with the DataFrame object’s tabular values derived from the uploaded CSV file. The result is a Figure in dictionary form containing the details of the desired plot.

After creating the Figure, the view function will pass the resulting dictionary to the Jinja2 template for rendition and display using Plotly’s JS library. However, JS can only understand the dictionary details if they are in JSON string format. Thus, use the json.dumps() method to convert the dictionary fig to string.

The following is the Jinja template that will render the graph using the Plotly JS library:

<!doctype html>
<html>
    <head>
        <title>Plotly Bar Graph</title>
    </head>
    <body>
        … … … … … …
        {%if graphJSON == '{}' %}
            <p>No plot image.</p>
        {% else %}
            <div id='chart' class='chart'></div>
        {% endif %}
    </body>
    <script src='https://cdn.plot.ly/plotly-latest.js'></script>
    <script type='text/javascript'>
            var graphs = {{ graphJSON | safe }};
            Plotly.plot('chart', graphs, {});
    </script>
</html>

The HTML script must reference the latest Plotly library from CDN. Then, a JS script must interpolate the JSON-formatted Figure from the view function with a safe filter to spare it from HTML escaping. Also, the JS must apply the plot() method of the Plotly class library to render the figure through the HTML’s <div> component. Figure 6.18 shows the bar graph generated by the create_plotly_stacked_bar() view function and displayed by its Jinja template.

Figure 6.18 – A bar graph created by Plotly

Figure 6.18 – A bar graph created by Plotly

Like Chart.js, the chart provides information regarding a data plot when hovered by the mouse. However, it seems that Chart.js loads faster than Plotly when the data size of the DataFrame object’s tabular values increases. Also, there is limited support for colors for the background, foreground, and bar shades, so it is hard to construct a more original theme.

The next JS library supports many popular PyData tools and can generate plots directly from pandas' DataFrame, Bokeh.

Visualizing data using Bokeh

Bokeh and Plotly are similar in many ways. They have interactive and 3D graphing features, and both need module installation. However, Bokeh is more Pythonic than Plotly. Because of that, it can transact more with DataFrame objects, especially those with large datasets.

To utilize the library, first install its module using the pip command:

pip install bokeh

Once installed, the module provides a figure class from its bokeh.plotting module, which is responsible for setting up the plot configuration. The following view implementation uses Bokeh to create a line graph showing the UK’s HPI values through the years:

from bokeh.plotting import figure
from bokeh.embed import components
@rendition_bp.route('/bokeh/hpi/line', methods = ['GET', 'POST'])
def create_bokeh_line():
    if request.method == 'GET':
        script = None
        div = None
    else:
        … … … … … …
        try:
            df = read_excel(uploaded_file, sheet_name=1, skiprows=[1])
            x = df.index.values
            y = df['UK']
            plot = figure(max_width=600, max_height=800,title=None, toolbar_location="below", background_fill_color="#FFFFCC", x_axis_label='Period by Quarter ID', y_axis_label='Nominal HPI')
            plot.line(x,y, line_width=4, color="#CC0000")
            script, div = components(plot)
        except:
            raise FileSavingException()
    return render_template('bokeh.html', script=script, div=div, title="Line Graph of UK's Nominal HPI")

After creating the Figure instance with the plot details, such as max_width, max_height, background_fill_color, x_axis_label, y_axis_label, and other related configurations, the view function can now invoke any of its glyph or plotting methods, such as vbar() for plotting vertical bar graph, hbar() for horizontal bar graph, scatter() for scatter plots, and wedge() for pie charts. The given create_bokeh_line() view utilizes the line() method to build a line graph with x and y values derived from the tabular values.

After assembling the Figure and its plot, call the components() function from bokeh.embed to wrap the plot instance and extract a tuple of two HTML embeddable components, namely the script that will contain the data of the graph and the div component that contains the dashboard embedded in a <div> tag. The function must pass these two components to its Jinja template for rendition. The following is the Jinja template that will render the div component:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Bokeh HPI</title>
        <script src="https://cdn.bokeh.org/bokeh/release/bokeh-3.2.2.js"></script>
    </head>
    <body>
         … … … … … …
        {%if div == None and script == None %}
            <p>No plot image.</p>
        {% else %}
        {{ div | safe }}
        {{ script | safe }}
        {% endif %}
    </body>
</html>

Be sure to have the latest Bokeh JS library in your HTML script. Since both div and script are HTML-embeddable components, the template will directly interpolate them with the filter safe. Figure 6.19 shows the outcome of rendering the create_bokeh_line() view function using the datasets:

Figure 6.19 – A line graph created by Bokeh

Figure 6.19 – A line graph created by Bokeh

Compared to that of Plotly and Chart.js, the dashboard of Bokeh is so interactive that you can drag the plot in any direction within the canvas. It offers menu options to save, reset, and wheel- or box-zoom the graph. The only problem with Bokeh is its lack of flexibility when going out of the box for more interactive features. But generally, Bokeh has enough utilities and themes to build powerful embeddable graphs.

From the degree of interactivity of the graphs and charts, let us shift our discussions to building real-time visualization approaches with Flask.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image