3 Triangle-Shaped Chart Ideas as Alternatives to Some Basic Charts
Many Charts are typically composed of rectangle or circle shapes, such as bar charts and pie charts. These charts are common and useful since they are not only easy to make, but also most people know how to read and understand them.
Even though they are suitable for many occasions, there are some scenarios that they may be too basic such as creating infographics or getting people's attention. Different methods can be applied to make the charts look more attractive. One of them is changing the charts' shape.


This article aims to provide ideas and guides on how to apply triangle-shaped charts as alternatives. This does not mean that they can replace the original charts. Each one has its pros and cons, depending on the purpose of use.
Triangle-Shaped charts
In total, three triangle-shaped charts will be explained in this article:
- Triangle bar chart
- Pyramid chart
- Ternary chart
Let's get started…
1. Changing the rectangular shapes in the bar chart with a Triangle Bar Chart
A bar chart is usually a visualization for comparing categorical data. Graphically, it presents rectangular bars in which the lengths show values of its category. With the same concept, triangle bar charts can do the same thing using triangles' height.
Next, let's see how we can create a triangle bar chart with Python.
Import libraries
We will mainly use functions from Matplotlib and Seaborn libraries for Data Visualization.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.patches import Polygon
import seaborn as sns
%matplotlib inline
Getting data
This article will work with randomly generated data using Numpy's random function. From the code below, the obtained data consists of three categories with the values of six months. If you want to plot the chart with other datasets, this step can be skipped.
Python">val1 = list(np.random.randint(10, 70, size=6))
val2 = list(np.random.randint(20, 90, size=6))
val3 = list(np.random.randint(15, 110, size=6))
val_all = val1 + val2 + val3
Define the position on the x-axis for locating each categorical value.
v1_xaxis = [i*3 for i in list(range(len(val1)))]
v2_xaxis = [i+0.8 for i in v1_xaxis]
v3_xaxis = [i+1.6 for i in v1_xaxis]
xaxis = v1_xaxis + v2_xaxis + v3_xaxis
Next, the for-loop function is used to iterate for plotting triangles. The following code also shows how to create a legend and label the x-axis.
plt.figure(figsize=(12.5,5))
sns.set_style('darkgrid')
ax = plt.gca()
color1 = ['darkorange']*6
color2 = ['orange']*6
color3 = ['lightyellow']*6
color_list = color1 + color2 + color3
## plotting triangle bar chart
for y, x, c in zip(val_all, xaxis, color_list):
tri = np.array([[x,0], [x+1,0], [x+0.5,y]])
pol = Polygon(tri,color = c)
ax.add_patch(pol)
## creating legend
lab1 = mpatches.Patch(color='darkorange', label='Category A')
lab2 = mpatches.Patch(color='orange', label='Category B')
lab3 = mpatches.Patch(color='lightyellow', label='Category C')
plt.legend(handles=[lab1, lab2, lab3])
## annotate the values at the top of each triangle
for x,y in zip(xaxis, val_all):
plt.annotate(y, (x+0.36, y+3))
## label x-axis
labels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
plt.xticks(v3_xaxis, labels)
plt.yticks([])
ax.set_xlim(-0.5, 18)
ax.set_ylim(0, 125)
ax.grid(False)
plt.show()
Ta-da !!

For comparison, the following bar chart shows exactly the same categorical values.

From the results, it can be noticed that both the triangle bar chart and the bar chart can express the same data. Since triangular shapes can indicate the direction, up and down, this is a good idea for showing positive and negative values or giving a sense of direction.
2. Stacking percentages with a Pyramid Chart
A pie chart is always a good option to show percentages. Same as the bar chart, this circular graphic is simple to make and easy to understand. But it is not the only option. If we think about the whole area as one hundred percent, other shapes can be used as well.
Here comes the Pyramid charts that use a triangular area to express percentages. Next, let's see how we can create this chart.
Start with defining variables and a function to obtain three coordinates from the percentage values (area) that we want to show.
sqt3 = 3**0.5 ## √3 value
h = sqt3/2 ## triangle height
area = sqt3/4 ## triangle ara
def tri_coordi(pct):
hy = (pct*area*sqt3)**0.5
y = h - hy
b =[(hy/sqt3)*-1, hy/sqt3]
return [y, b[0], b[1]]
In this article, the pyramid chart is created by layering triangles on top of each other. They are plotted using the same point at the top. The triangles with more area are plotted first. The percentage of an area, that we want to show, must subtract the triangle area located above.
From the previous paragraph, if I want to show a pyramid chart consisting of 15%, 20%, 25%, and 40% respectively, the percentages of the created triangles must be 15%, 35%, and 60%. The last 40% will be shown in the area in the first layer. These numbers can be modified, if you want to use other values.
## percentages of the triangles
percent1 = 0.15
percent2 = 0.35
percent3 = 0.60
## get coordiantes
n1 = tri_coordi(percent1)
n2 = tri_coordi(percent2)
n3 = tri_coordi(percent3)
Next, Matplotlib's Polygon function is used to create the triangles.
plt.figure(figsize=(9.5, 5))
sns.set_style('darkgrid')
ax = plt.gca()
s1 = np.array([[n1[1], n1[0]], [n1[2], n1[0]], [0,h]])
s2 = np.array([[n2[1], n2[0]], [n2[2], n2[0]], [0,h]])
s3 = np.array([[n3[1], n3[0]], [n3[2], n3[0]], [0,h]])
s_base = np.array([[-0.5,0], [0.5,0], [0,h]]) ## the base
pol1 = Polygon(s1,color = 'darkorange')
pol2 = Polygon(s2,color = 'orange')
pol3 = Polygon(s3,color = 'khaki')
pol_base = Polygon(s_base,color = 'lightyellow')
ax.add_patch(pol_base)
ax.add_patch(pol3)
ax.add_patch(pol2)
ax.add_patch(pol1)
ax.set_xlim(-0.9,0.9)
ax.set_ylim(-0.1,1)
ax.grid(False)
## annotate the values
list_h = [n1[0], n2[0], n3[0], 0]
val = ['15%', '20%', '25%', '40%']
text = ['Category A', 'Category B', 'Category C', 'Category D']
for txt, v, hi in zip(text, val, list_h):
plt.annotate(txt + ' ' + v, (-0.11, hi + 0.05))
plt.xticks([])
plt.yticks([])
plt.show()

For comparison, the pie chart below contains the same percentages.

There is a limitation that must be mentioned here. While the pie chart is divided by the circle's radius, the pyramid chart is sliced by lines with different lengths. Even if having the same area size, the area shapes on the top and bottom are unalike. From the result, it can be noticed that the height of 15% area is higher than 25% area.
Another difference between these two charts is the direction of components. If the sequence needs to be shown, the pie chart can locate categories in clockwise and anticlockwise directions, while the pyramid chart can express categories in up and down directions.
As previously mentioned, every chart has its pros and cons. Even though the pyramid chart cannot replace the pie chart. It can be useful if the goal is to make the reader focus on the relationship in the vertical direction.
3. Handling three variables with a Ternary Plot
When it comes to dealing with three continuous variables, a 3D plot is always a primary option. However, this is not the only choice available. A ternary plot is another chart using an equilateral triangle to show three variables data.
This chart is useful in scientific studies, such as chemistry and mineralogy, to express three components. Please take into account that the data shown in this plot is the ratios of three variables that have a sum equal to one.
Getting data
To show that the method explained here can apply to real-world datasets, we will use the ‘Air pollution in Seoul' dataset. The data was originally provided by the Seoul Metropolitan Government, and it can be downloaded from Kaggle. This dataset is used under the public domain type 1: attribution.
Let's import the dataset.
df = pd.read_csv('/Measurement_summary.csv')
df.head()

We get air pollutants data such as SO2, NO2, CO, and O3 between 2017 and 2019 from 25 districts in Seoul, South Korea. The next step is selecting the air pollutants, district number, and the time period.
This article will plot the ratio between SO2, NO2, and O3. The CO values will be used to map colors to the values. If you want to work with other criteria, the following code can be modified.
df_s = df[['Measurement date', 'Station code',
'SO2', 'NO2', 'O3', 'CO']]
df_s = df_s[(df_s['Station code']==101) & (df_s['CO'] > 0)]
df_s['Date'] = pd.to_datetime(df_s['Measurement date'])
df_s = df_s[(df_s['Date'].dt.time >= pd.to_datetime('09:00:00').time()) &
(df_s['Date'].dt.time <= pd.to_datetime('16:00:00').time())]
df_s.head()

Now that we have done with the dataset, the scatter_ternary function from Plotly can help us create a ternary plot with just a few lines of code. An advantage of using Plotly is the created chart is interactable.
import plotly.express as px
fig = px.scatter_ternary(df_s, a="SO2", b="NO2", c="O3",
color="CO", range_color =(0,3),
color_continuous_scale='viridis', opacity= 0.95)
fig.update_traces(marker_size = 13.2)
fig.update_layout(width=900, height=600)
fig.show()
Voilà!!

The same dataset is displayed in a 3D scatter plot below for comparison.

From the results, the ternary plot can show three variables data, including one more variable for mapping colors. By the way, please be aware that the data shown in the ternary plot are ratios of three variables that have a sum equal to one. They are not the real amount. This can be considered as a limitation of using this chart.
Key takeaways
Changing the basic chart's shape can be a good option for creating an attractive result. This article shows triangle-shaped chart ideas as alternatives to bar charts, pie charts, and some 3D plots. However, this does not mean they can replace the other charts.
Each data visualization has pros and cons, depending on various factors and the purpose of use.
I'm quite sure that there are other charts that can also be applied as alternatives. The ideas shown here are just some examples. If you have any suggestions, please feel free to leave a comment. I would be happy to read.
Thanks for reading.
These are other articles about data visualization that you may find interesting.
- 8 Visualizations with Python to handle Multiple Time-Series data (link)
- Data Visualization cheat sheet for Basic Machine Learning (link)
- 9 Visualizations that Catch More Attention than a Bar Chart (link)
- 9 Visualizations to show Proportions or Percentages instead of a Pie chart (link)
References
- 열린데이터광장 메인. 서울열린데이터광장. https://data.seoul.go.kr
- Seoul Metropolitan Government. (2021, May). Air Pollution Measurement Information in Seoul, Korea. Retrieved April 24, 2022 from https://www.kaggle.com/datasets/bappekim/air-pollution-in-seoul
- Wikimedia Foundation. (2024, July 28). Ternary plot. Wikipedia. https://en.wikipedia.org/wiki/Ternary_plot