Real-Time Interactive Plotting (using Sockets, Python & Plotly)
Tags: python, sockets, plotly, graph
Published: 2021-07-09 17:23:52

![GIF showing result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x4lirjpzy821xg34wngy.gif)
There might be times where you need to plot a graph of stock prices of a company, data from a sensor, or even CPU usage of your computer. All these are examples of real-time data where there is little to no delay between data collection and retrieval.

In this article, I will explain the server-side implementation of a real-time plotting system. For the client-side, pleaser refer to [this article](https://dev.to/boidushya/real-time-interactive-plotting-client-side-using-sockets-react-hooks-plotly-1291) 

The real-time communication between the server and client is achieved by using WebSockets. You can learn more about web sockets [here](https://www.w3.org/TR/websockets/)

I'll be using the following libraries/frameworks and languages:

- Python
- React
- Python-SocketIO
- Plotly (Python)

I have also used Pandas & YFinance to fetch stock details but you can plug in your own data source.

### Project setup

 Create a python virtual environment and activate it
```sh
python3 -m venv venv
source venv/bin/activate
```

Install requirements. The entire list of dependencies can be found here - [requirements.txt](https://gist.github.com/radioactive11/0fbee51f6d3cc80ab348bf31ac21ee48)

```sh
pip3 install -r requirements.txt
```

### Socket Connection Handling

Here I've handled the connection, disconnection, and sending the data to the client.



When a client connects to the server, a unique ID (session ID or Sid) is alloted to the client for further references during communications.

I stored this unique ID as `sid` inside a list which holds all these `sid`s  of the connected clients. Once a client disconnects (which is generally by closing the browser tab), I remove the `sid` of that particular client from the list. 

The client emits an event called `ping_graph`. The event handler `ping_graph`(line 22-34) is responsible for  **pinging** the client continuously with the data it requested for (in this case symbol of the company for which it wants the plot for)

A while loop runs as long as the client is connected with the server and keeps sending data (in this case the *jsonified*) version of the graph. Once the client disconnects, the loop stops running.

{% gist https://gist.github.com/radioactive11/398ae0f3089326ab058f01a14708bd6f %}


### Plotting the data

Now coming to the part where we actually plot the data. I used a library called [Plotly](https://plotly.com) which allows to create interactive plots easily in python.

I fetch stock data of a company from `yfinance` with 1 minute interval. Next I plot a mountain graph using the data. I've set the line color to change depending on whether the prices increase, decrease, or stay the same. I also added some buttons which will allow quick switching between ranges.

Finally, I converted the entire figure to a JSON object which will be sent to the client side for rendering.

{% gist https://gist.github.com/radioactive11/1d26a03f50833a35ea4b522e260ba836 %}

The steps to render the plot in using React can be found [here](https://dev.to/boidushya/real-time-interactive-plotting-client-side-using-sockets-react-hooks-plotly-1291)

### Run the Socket.IO server

I use `gunicorn` and `eventlet` to run the Socket.IO serever
```sh
export PYTHONPATH=src
gunicorn -k eventlet -w 1 --reload src.main:app
```

<strong>Note:</strong> This is what the directory structure looks like. 
```
/
src/
├─ main.py
├─ scripts/
│  ├─ plot.py
requirements.txt
```

Link to GitHub Repository: [Real Time Plot](https://github.com/radioactive11/real-time-plot) 

Photo by <a href="https://unsplash.com/@techdailyca?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Tech Daily</a> on <a href="https://unsplash.com/s/photos/graph?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>