Visualizing Data in the Terminal: A Simple Guide to Building a Customized Data Visualization Tool
Tags: datascience, python, api, programming
Published: 2023-03-15 11:20:39

As technology advances so does the amount of data generated and collected. With the rise of APIs, it has become easier than ever to access vast amounts of data. However, analysing and interpreting this data can be challenging without the right tools. In this article, we will explore how to build a program that can visualize data from an API in the terminal. This program can be a useful tool for anyone who needs to quickly analyze and interpret data without using complex visualization software.

## Prerequisites

- Basic programming skills. Python knowledge is a nice-to-have because that is the language we will be using.
- [Python 3.8](https://www.python.org/downloads/release/python-380/) and above installed on your local machine.
- Access to the terminal or command line as the program will be executed on the terminal or command line.

## Building our Data Visualization Tool

Imagine we want to track the growth of the user base of a new product over time and analyze usage patterns to inform product decisions. We have access to an API endpoint that returns the number of users on specific dates, but we need a way to quickly and easily visualize this data. The program will:

- Accept the time boundaries (i.e, start date and end date)
- Fetch data from an API based on the start and end date.
- Visualize the data as a graph on the terminal.

The first thing we will do is create a folder for the project.  Let's name this folder `visualize`. Inside the folder, create a file called `visualize.py`. Then we `cd` into the folder and create a virtual environment. The virtual environment is an isolated space that enables us to install and manage Python modules and packages required for the project. So instead of installing packages globally, we can install them just for a specific project.

To create a virtual environment, run:

```sh
cd visualize
python3 -m venv env
```

Then we need to activate the virtual environment.
On Linux:

```sh
source ./env/bin/activate
```

On Windows:

```sh
env\Scripts\activate.bat
```

### Accepting and parsing input from the terminal

To collect input from the terminal, we can use flags and arguments. Flags are also known as options, and they usually start with a dash (-). So to run our program when we are done, we would run a command like this:

```sh
python3 visualize.py -s <START DATE> -e <END DATE>
```

The `-s` and `-e` flags specify the `START DATE` and `END DATE` arguments respectfully. To parse flags and arguments from the terminal, we need to install a python module named argparse. To install, run:

```sh
pip install argparse
```

Then, in our `visualize.py` file, we import `argparse` and write a function to parse input from the terminal.

```python
import sys
import argparse

def parse_arguments(args):
    try:
        parser = argparse.ArgumentParser(
            description='Visualize Data within a time frame', prog='visualize')
        parser.add_argument('-s', '--start-date', required=True,
                            help='Start date. Date format: DD-MM-YYYY', type=date)
        parser.add_argument('-e', '--end-date', required=True,
                            help='End date. Date format: DD-MM-YYYY', type=date)

        parsed_arg = parser.parse_args(args)
        return parsed_arg
    except argparse.ArgumentError as err:
        sys.exit(err)
    except argparse.ArgumentTypeError as err:
        sys.exit(err)


def date(date_string):
    return datetime.strptime(date_string, '%d-%m-%Y').date()
```

In the code snippet above, we create the `ArgumentParser` object. We can then specify a description text with the description parameter. The `prog` parameter specifies the name of the program. Next, we add arguments that we expect to be supplied when running the program. In our program, we need the `start_date` and the `end_date` arguments. So we can add arguments using the `add_argument()` method. In this method, we provide the flag that specifies the argument in both short and long format, for example, `-s` and `--start-date` for the `start_date` argument. We also specify if the argument is required or not.

We then have to specify the type of the arguments, which in our case, is the date type. We write a function that parses a date string into python date format and returns the date format. Finally, we add an explanation of the argument which will be displayed if we run the program incorrectly. We do all these for both the `start_date` argument and the end_date arguments. Then we parse the arguments using the `parse_args()` method. Finally, we return the parsed arguments.

### Getting coordinates for plotting the graph

Next, we want to get all our coordinates for plotting our graph. We create a function that accepts the parsed arguments as a parameter and then returns our x and y coordinates.

```python
def get_coordinates(args):
    x_values = []
    y_values = []


    api_data = {
        "01-01-2022": 300,
        "02-01-2022": 500,
        "03-01-2022": 700,
        "04-01-2022": 1300,
        "05-01-2022": 2000,
        "06-01-2022": 3000,
        "07-01-2022": 3500,
        "08-01-2022": 4000,
        "09-01-2022": 4500,
        "10-01-2022": 5000,
        "11-01-2022": 20000,
        "12-01-2022": 35000,
        "13-01-2022": 46000,
        "14-01-2022": 70000,
        "15-01-2022": 90000
    }
    start_date = args.start_date
    end_date = args.end_date

    if start_date.strftime('%d-%m-%Y') in api_data and end_date.strftime('%d-%m-%Y') in api_data:
        for key, value in api_data.items():
            if date(key) >= start_date and date(key) <= end_date:
                x_values.append(date(key))
                y_values.append(value)
    elif start_date.strftime('%d-%m-%Y') not in api_data:
        sys.exit("Given start date is not available")
    elif end_date.strftime('%d-%m-%Y') not in api_data:
        sys.exit("Given end date is not available")
    else:
        sys.exit("An error occurred. Please check your input")

    coordinates = {
        "X": x_values,
        "Y": y_values
    }
    return coordinates
```

First, we have our API data. In the `get_coordinates()` function, create the `x_values` and `y_values` lists (also known as arrays in other languages) that will hold values of our x-axis and y-axis. We then initialize a variable, `api_data`, which is a dictionary (also known as Maps or HashMaps in other languages ) to hold mock API data for testing purposes. In a production environment, this variable would be replaced with actual data retrieved from an API.

We then check if the start and end dates provided are available in the `api_data`. If they are available, we loop through the `api_data` dictionary and add the dates and values that fall within the range of the start and end dates specified in the arguments to the `x_values` and `y_values` lists, respectively.

In the loop, we use the `date()` function created earlier to parse date strings in our API data. The `x_values` and `y_values` lists represent the dates and number of users, respectively. If the start date or end date is not available in the res dictionary, the script exits with an appropriate error message. Then, we return the coordinates as a dictionary.


### Plotting the graph

To plot the graph, we will use a python package called [plotext](https://github.com/piccolomo/plotext). Plotext lets you plot scatter, line, bar, histogram, and date-time plots (including candlesticks) directly on the terminal. 
First, we need to install this package.

```sh
pip install plotext
```

Then we import `plotext` in our code and write a function that takes the coordinates and plots a bar chart directly in the terminal using `plotext`.

```python
import plotext as plt

def visualize_data(data):
    # data = get_data(args)

    plt.title("User Base Growth Graph")
    plt.ylabel("Number of Users")
    plt.xlabel("Dates")
    plt.date_form('d/m/Y')

    no_of_users = data.get("Y")
    dates = plt.datetimes_to_string(data.get("X"))


    plt.yticks(no_of_users)
    plt.bar(dates, no_of_users)

    plt.show()
```

In the `visualize_data` function, the labels for our y-axis and x-axis are set using the `xlabel()` method. We also specify the format to display our dates. Then we get the values of our y and x-axis as the variables, `dates`, and `no_of_users`. We need to convert our x values (date objects) to strings. Finally, we can plot our bar chart with the `bar()` function, passing in x and y values as `dates` and `no_of_users`.

### Running our program

At the end of our program, we need to call the functions we created.

```python
args =  parse_arguments(sys.argv[1:])
coordinates = get_coordinates(args)
visualize_data(coordinates)
```

The arguments are first gotten from the terminal using the python `sys` module and then parsed in the `parse_arguments()` function. The parsed arguments are then passed into the `get_coordinates` function. Finally, the `visualize_data` gets the coordinates and visualizes the data.
To run this program, we will cd into our project folder and run this command.

```sh
python -m visualize -s <START DATE> -e <END DATE>
```

Replace `<START DATE>` and `<END DATE>` with their respective values.
The output on our terminal will look like this:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wbmehb5rb26fp4deznhd.png)

Or like this, depending on your terminal:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q280vd3pk7akyuhd5hci.png)

## Conclusion

Data visualization in the terminal can be a powerful tool for analyzing and interpreting data without the need for complex visualization software. By using Python and libraries such as Plotext, you can quickly and easily create powerful visualizations that help you make data-driven decisions. Whether you're tracking user growth or analyzing sales data, a terminal-based visualization tool can help you streamline your analysis and make sense of complex data.

In this article, we have demonstrated how to build a Python program to visualize data directly on the terminal. We handled input from the terminal using the `argparse` library, then processed and transformed both the parsed terminal input and API data for plotting. We then plotted a bar chart using the `plotext` package.

You can get the example code discussed on [GitHub](https://github.com/DonTee-Why/visualize). Cheers!

## Further Reading

- [Plotext](https://github.com/piccolomo/plotext)