Suicide Rate Analysis — Interactive Dashboard with Taipy in 2 Hours

Try Taipy with the simple augmented mark-down syntax to streamline your coding process to build interactive visualizations in Python

Chi Nguyen
12 min readMay 8, 2023
Photo by Pineapple Supply Co. on Unsplash

The story continues…

After 2 previous parts introducing the Taipy package with:

  • Part 1: Introducing a general idea of how Taipy GUI works and showing how different basic charts are created.
  • Part 2: Applying more visual control elements

In this article, I will show you how to utilize what we know about Taipy GUI and take things to the next level. We’ll dig further into the data to find trends and insights that will help us comprehend this issue in a more detailed manner.

Get ready to watch how Taipy GUI speeds up our finished dashboard!

Purpose of This Dashboard

Everyone is aware that suicide is not a good way to solve problems. But, the cruel reality is that millions of individuals attempt suicide every year, and many have been able to end their lives. I’ll analyze the suicide situation globally in this dashboard to see how it has changed over the 35 years since 1985 in different nations.

Data Overview & Questions

We are still using the suicide data that we have been using for the previous 2 parts. To remind you, the data is a dataset on Suicide Rates (1985 to 2021) of different countries (License CC0: Public Domain), which is available on Kaggle. Here is a glimpse of this data.

Image 1 — Data Overview

Since the data has no missing values in the fields we will work with, we do not have to worry about this issue. However, as the data on Korea’s suicides per 100k in 2020 is all 0, we have the right to suspect the quality of this data. I decided to delete this data from the data set for a more trustful analysis. Furthermore, 7 countries were removed as they have <= 3 years of data total.

With the information provided, I plan to divide this data set into 3 parts to conduct further analysis. In each part, the analysis will be gradually developed by responding to various questions:

Global Analysis

I will look at how suicide numbers worldwide have changed over 35 years, since 1985. Specifically, the statistics can be observed from different angles: ages, genders, generations, etc. For example:

  • What were the overview numbers of suicides worldwide? (e.g.: Trend, Highest/Lowest Average Suicides per 100K,..)
  • Were there any differences in suicide numbers between different age groups? Which group appeared to have the most suicides per 100K population? At what time? Did this group's age remain the same as the group with the highest suicide number in 35 years?
  • Were there any differences in suicide rates between women and men?

Country Analysis

  • What were the top 10 countries that have the highest number of suicides?
  • Is there anything in common between these countries?

Relationship Analysis

  • Are there any relationships detected between GDP and Suicides Rates?

Visualization with Taipy

When we have the outline of what we should do, we come to the stage where we will find out the answers to questions raised in the previous part.

A bit of introduction to Stylekit

People who are not familiar with user interface design may feel some struggles in customizing their dashboard pages when using CSS, but I think this problem was resolved as the Taipy team has just released “the Stylekit”. With this new package, CSS variables are set by default for graphical features like color or spacing values that are easy to personalize.

For example, instead of having a long code to define the color and the font like this

<center><h1 style="background-color:white; color:#14344b; font-family:Arial; font-size:3vw"> IS SUICIDE RATE <span style="background-color:white; color:#38a7b8">INCREASING?</span></h1> </center>

Now, you just have to define the format like this, and “Stylekit” will take care of everything.

# IS SUICIDE RATE *INCREASING?*{: .color-primary}

It’s very simple, right? It can save you a ton of time designing the dashboard with just some specifications and a click after everything has been done.

This is the dashboard before applying this automatically designed GUI package:

Here is the dashboard with the “stylekit” package.

More information about Taipy GUI’s stylekit can be found here.

Also, you can take a look at the optimized code with Stylekit applied in this repository.

Now, let’s start building our dashboard!

Global Analysis

Yearly Change: Overview

A line chart will be suitable to visualize the change in suicide rates over 35 years since 1985.

## Getting the data 
world_suicide = (
data.groupby("year")
.agg({"suicides/100k pop": "mean"})
.rename(columns={"suicides/100k pop": "Total suicides per 100k"})
.reset_index()
)
world_suicide["Total suicides per 100k"] = round(world_suicide["Total suicides per 100k"], 2)

## Taipy visualization
### Formating chart
layout = {"hovermode": "x"}
options = {"unselected": {"marker": {"opacity": 0.75}}}

### Taipy syntax
avg_worldwide = """
### **Worldwide**{: .color-primary} Suicide (per 100k) by Years <br/> <br/> \
<|{world_suicide}|chart|type=line|x=year|y=Total suicides per 100k|layout={layout}|height=100%|>
"""

## Run Taipy GUI
gui = Gui(avg_worldwide)
gui.run(dark_mode=False, port=5000)

It is obvious that there was a decrease in suicides after 1995. Yet, it considerably increased in 2016 before sharply falling in 2020. The worldwide COVID-19 pandemic outbreak in 2020 changed the ways we live dramatically and abruptly. Contrary to what some may have expected, suicide deaths were reduced to a very low number during this difficult time, despite the stress and the fear many people faced. A few reasons are contributing to this:

  • Increase in access to mental health resources: Mental health was the most considered and taken care of when people were quarantined. Remote mental health support services were provided more often and easily accessed than ever.
  • As a result of the first reason, mental health concerns are pushed to the center of public debate. This led to a reduction in the stigma related to mental illness, and thereby serious solutions were sought and applied.
  • Greater sense of community: As a result of individuals joining together to help one another during tough circumstances, the pandemic boosted the social sense of unity and sympathy.

Genders vs. Suicides

Worldwide suicides between genders are also discovered through a line chart of 2 groups over 35 years. Besides, we can use a bar chart to demonstrate the % of suicides between men and women, and card visuals to display the average suicides per 100K of both men and women. Then, we find out the insights based on what we observed.

## Suicides by gender
world_suicide_sex = (
data.groupby(["year", "sex"]).agg({"suicides/100k pop": "mean"}).reset_index()
)
world_suicide_sex["suicides/100k pop"] = round(
world_suicide_sex["suicides/100k pop"], 2
)

## Prepare data for Taipy line chart visualization
df_sex = world_suicide_sex.set_index(["year", "sex"]).unstack()
df_sex.columns = [f"{i}_{j}" for i, j in df_sex.columns]
world_suicide_sex = df_sex.reset_index()

## Taipy line chart
gender_line =
"""
### Worldwide Suicide (per 100k) by **Genders**{: .color-primary}
<|{world_suicide_sex}|chart|mode=lines|x=year|y[1]=suicides/100k pop_female|y[2]=suicides/100k pop_male|color[1]=#14344b|color[2]=#38a7b8|height=900px|>
"""

## Run Taipy GUI
gui = Gui(gender_line)
gui.run(dark_mode=False, port=5001)

Men have committed suicide at a greater rate than women. It wasn’t until 2017 that the gap started to narrow down.

## Gender and %suicides
gender_pct = pd.DataFrame(
{
"Gender": ["Female", "Male"],
"% Suicides": [
round(
sum(world_suicide_sex["suicides/100k pop_female"])
/ sum(
world_suicide_sex["suicides/100k pop_female"]
+ world_suicide_sex["suicides/100k pop_male"]
),
2,
),
round(
sum(world_suicide_sex["suicides/100k pop_male"])
/ sum(
world_suicide_sex["suicides/100k pop_female"]
+ world_suicide_sex["suicides/100k pop_male"]
),
2,
),
],
}
)
## Taipy pie chart
layoutpie = {
"piecolorway": ["#38a7b8", "#14344b"],
}
gender_pie =
"""
### % of Suicides **Men vs. Women**{: .color-primary} <br/> <br/>\
<|{gender_pct}|chart|type=pie|values=% Suicides|labels=Gender|layout={layoutpie}|>
"""

## Run Taipy GUI
gui = Gui(gender_pie)
gui.run(dark_mode=False, port=5002)

From the pie chart, we can see that the overall number of suicides among males was, on average, three times that of women.

This figure can also be viewed in numbers. For example, I will show you how Taipy supports the metrics display.

metrics = """
<avg_suicides|part|class_name=metrics|
**18.55**

Average Suicides per 100K of Men
|avg_suicides>

<avg_suicides|part|class_name=metrics|
**5.12**

Average Suicides per 100K of Women
|avg_suicides>
"""

Ages vs. Suicides

Similarly, we can discover the change in suicide deaths in different age groups over 35 years with a line chart. A pie chart of suicide percentages between age groups can also be generated like the way we did with genders.

age_line = """ 
### Worldwide Suicide (per 100k) by **Ages**{: .color-primary} <br/> <br/>\
<|{world_suicide_age}|chart|mode=lines|x=year|y[1]=suicides/100k pop_5-14 years|y[2]=suicides/100k pop_15-24 years|y[3]=suicides/100k pop_25-34 years|y[4]=suicides/100k pop_35-54 years|y[5]=suicides/100k pop_55-74 years|y[6]=suicides/100k pop_75+ years|color[1]=darkblue|color[2]=#4f6871|color[3]=#112635|color[4]=#bf5550|color[5]=#009681|color[6]=#ffd10c|height=900px|>
"""

age_pie = """
###% of Suicides between **Age**{: .color-primary} Groups <br/> <br/> \
<|{age_pct}|chart|type=pie|values=% Suicides|labels=Age|layout={pieage}|>
"""

The 75+ age group remains the age group with the most people committing suicide from 1985 to 2016. However, after 2016, the number of suicides in this group decreased dramatically, and the 35–54 age bracket replaced the 75+ group position as the age with the most suicide deaths. In total, it appeared that the number of suicides tended to increase in later life when people got older. The main causes, according to AAFMT, can be attributed to serious depression, which is frequently associated with suicide in later life. Besides, older persons do not often seek treatment for mental health issues, so that’s why their situation tends to become worse as time passes.

Visual control elements & Layout

For example, I want a selection bar for observing the suicide number according to different categories at the top of the page: global suicide by year, global suicides by gender, and global suicide by age. All the charts and corresponding information will appear according to what I click.

By using the toggle element, here is what I should do:

## Create toggle
<|toggle|theme|>
<|{selection}|toggle|lov=Global Suicides by Years;Global Suicides by Genders;Global Suicides by Ages|>

## Defining each part of toggle selection
### If people select "Global Suicides by Years"
<global_suicides|part|render={selection=='Global Suicides by Years'}|
<|chart1|>
<|chart2|>
|>

### If people select "Global Suicides by Genders"
<gender|part|render={selection=='Global Suicides by Genders'}|
<|chart1|>
<|chart2|>
|>

### If people select "Global Suicides by Ages"
<ages|part|render={selection=='Global Suicides by Ages'}|
<|chart1|>
<|chart2|>
|>

And to have the layout as in the picture below:

## Clarify the layout 
<|layout|columns= 2 1|
<|Chart1|>
<|
<|Chart2|height=1/3*chart1's height|>
<|Chart3|height=1/3*chart1's height|>
<|Chart4|height=1/3*chart1's height|>
|>
|>
Layout

Country Analysis

I am interested in finding which are the top 10 countries that have the highest suicide rate per 100K population. Then, for each country, I intend to see the country's average suicides over 35 years together with the development of that country in terms of GDP per capita values. The only complicated task here is to connect the country information with every selection of the country dropdown menu. However, this has been mentioned in the previous control element article. Therefore, in this post, I will only specify the know-how of presenting the charts under the Taipy layout but not go into further explanations.

## Taipy layout 
layout = """
## **Korea**{: .color-primary} Has The Highest Suicide Rate

<|{selected_country}|selector|lov={listtop}|dropdown|on_change=on_change_country|label=Selected Country|>

<|layout|gap=30px|columns=60 40|
### **Top 10**{: .color-primary} Countries with The Highest Suicide Rates <br/> <br/>\
<|{df_world_country}|chart|type=bar|y=country|x=Suicide Rate|properties={prop_bar}|height=800px|>

<right_col|
### Country **Average**{: .color-primary} Suicide by Year <br/> <br/>\
<|{data_country}|chart|type=line|x=year|y=Total suicides|layout={layout}|height=400px|>

### **Gdp**{: .color-primary} per Capita by Year <br/> <br/>\
<|{gdp_country}|chart|type=line|x=year|y=gdp_per_capita|layout={layout}|height=400px|>
|right_col>
|>
"""

While Korea has the most case of suicides per 100K population, 6/10 countries in the top 10 were part of the Soviet Union. Due to some research, the high number of suicide cases in the Soviet Union may be partly associated with its legacy. Economic instability, social unrest, and cultural perceptions of mental health difficulties are some of these reasons.

When looking at the charts of GDP, I realize that gdp_per_capita has no difference from 1990 to 2000. After a period of the economic situation remained stagnant, the countries’ GDPs started growing slightly after. Meanwhile, some countries’ suicide deaths show a downward trend starting in 2000. This raises the question of whether there is a correlation between suicides and GDP. That’s why I decided to find the relationship between the 2 factors.

Relationship Analysis

My idea in this part is first to find the coefficient between GDP and the number of suicides of the top 10 countries and then look at the regression of each country to verify the relationship.

## Find the correlation coeff between gdp per capital and suicides/100k population
corr_try = {}
for country in listtop[:11]:
slope, intercept, r_value, p_value, std_err = stats.linregress(
gdp_agg[gdp_agg.country == country]["gdp_per_capita"].values,
gdp_agg[gdp_agg.country == country]["suicides/100k pop"].values,
)
corr_try[country] = float(r_value)
corr_eff_data = pd.DataFrame.from_dict(corr_try, orient="index")
corr_eff_data.reset_index(inplace=True)
corr_eff_data = corr_eff_data.rename(columns = {'index':'Country',0:'Correlation Coeff'})

## Linear Relationship?
gdp_agg = (
data.groupby(["country", "year"])
.agg({"gdp_per_capita": "mean", "suicides/100k pop": "mean"})
.reset_index()
)

### Regress data point
def do_regression(data):
x = data['gdp_per_capita'].values.reshape(-1, 1)
y = data['suicides/100k pop'].values.reshape(-1, 1)
model = LinearRegression()
model.fit(x, y)
data['predictions'] = model.predict(x)
return data
regression_chart = do_regression(gdp_agg)

### Initialize variables for selector
countries = ['All countries'] + listtop_countries
selected_countryy = 'All countries'

### When the selected value of the country selector changes
### Call this function
def update_regresion(state):
if state.selected_countryy == 'All countries':
temp_data = gdp_agg.copy()
else:
temp_data = gdp_agg[gdp_agg['country'] == state.selected_countryy]

state.regression_chart = do_regression(temp_data)

## Taipy Layout
relationship = """
## The Suicide Rate is **Highly Correlated**{: .color-primary} to The Gdp per Capita of Top 10 Countries

<|{selected_countryy}|selector|lov={countries}|dropdown|on_change=update_regresion|label=Selected Country|>

<|layout|gap=30px|columns=1 1|
### **Correlation**{: .color-primary} Coeff. of GDP vs. Suicide Rates <br/> <br/>\
<|{corr_eff_data}|chart|type=bar|y=Correlation Coeff|x=Country|color=#14344b|height=600px|>

### **Regression**{: .color-primary} Plot of GDP per Capita & Suicide Rates <br/> <br/>\
<|{regression_chart}|chart|x=gdp_per_capita|y[1]=suicides/100k pop|y[2]=predictions|mode[1]=markers|mode[2]=lines|height=600px|>
|>
"""

As a result, we can say that the suicide rate is highly correlated to the gdp_per_capita of the top 10 countries. Especially, 9/10 countries’ suicide rates are negatively related to gdp_per_capita except for Korea. One possible reason to support this is that the more economic growth, the more stable and fulfilled society, which in turn lessens pessimism and despair in individuals. However, Korea is an exception. While having a high GDP per capita, the country still has a very high number of suicide cases. The causes might be due to factors such as social isolation, strong academic and job expectations, and societal attitudes toward mental health.

CSS Customization

In order to get the customization as desired, we need some clarification for our elements in CSS.

/*center every graph, text, ...*/
:root {
text-align: center;
}

/*Possibility to color a text (example title)*/
.color-primary {
color:rgb(56, 167, 184)
}

/*Create a metric card*/
.metrics{
color: white;
background-color: rgb(20, 52, 75);
}

/*Change the default behaviour of a second title ('##' in Markdown)*/
h2{
text-align: left !important;
color:rgb(20, 52, 75) !important;
background-color: rgb(56, 167, 184) !important;
margin: 5px !important;
}

/*Change the default behaviour of a third title ('###' in Markdown) */
h3{
color: rgb(20, 52, 75) !important;
}

/*Change the default behaviour of bold text ('**' in Markdown) */
strong{
color:white;
font-size: x-large;
}

Then, with just one click to connect our dashboard to the figuration:

import os

# Run Taipy GUI
gui = Gui(tryy, css_file="taipy/main.css", path_mapping={"taipy": "D:/Jupyter Notebook/taipy"})
gui.run(dark_mode=False, port=5007, path_mapping={"taipy": "D:/Jupyter Notebook/taipy"})

And voila! The final result is out!

Key takeaways

As you can see, I have spent just 2 hours discovering Taipy GUI, and I think the final dashboard turns out to be quite decent. You definitely can create more beautiful ones with deeper analysis if you spend more time with this interesting package.

With the help of Taipy, I can easily create a dashboard real quick. It is convenient in many ways with some obvious advantages as:

  • gui customizations do not require advanced programming skills
  • you do not have to write long codes for charts
  • package offers a wide range of charts
  • the syntax is concise and easily understood
  • different types of visual control elements and can easily be applied
  • the package is actively developed and maintained with new features and upgrades routinely
  • the Taipy team is extremely supportive and your questions will be answered in a very short time

Last words

It has been a fun time to explore the Taipy package and produce fast and effective dashboards. I will definitely come back with this package in the future for more high-quality projects.

--

--

Chi Nguyen

MSc in Statistics. Sharing my learning tips in the journey of becoming a better data analyst. Linkedin: https://www.linkedin.com/in/chinguyenphamhai/