2D Histograms with Plotly. How to create more informative... | by Soner Yıldırım | Towards Data Science

Plotly Python (plotly.py) is an open-source plotting library built on plotly javascript (plotly.js). One of the things I like about plotly.py is that it offers a high-level API (plotly express) and a low level API (graph objects) to create visualizations. With plotly express, we can create a dynamic and informative plot with very few lines of code. On the other hand, we need to write more code with graph objects but have more control over what we create.
In this post, we will create 2D histograms, also called density plots, using plotly express.
Histograms are commonly used plots in data analyses to get an overview of the distribution of data. In histograms, the distribution of numerical or categorical data is shown with bars. Each bar represents a value range or category and the height of the bar is proportional to the number of values that fall into that range.
Let’s first create 1D histograms and then upgrade to 2D histograms (or density maps). We will use the famous titanic survival dataset which is available here on Kaggle.
We start with reading the data into a pandas dataframe:
import numpy as npimport pandas as pddf = pd.read_csv("/content/titanic_train.csv")print(df.shape)df.head()
I only use the training dataset which includes data of 891 passengers. We first create histograms on “Age” and “Fare” columns.
#import plotly expressimport plotly.express as pxfig = px.histogram(df, x="Age",                   title="Histogram of Age",                   width=800, height=500)fig.show()
We have a wide range of ages but mostly between 20 and 30. Let’s see how the distribution of “Fare” column looks like.
There are some extreme values in the fare column. For demonstration purposes, I will drop the rows with a fare greater than 100. These rows comprise approximately 6% of the entire dataset.
len(df[df.Fare > 100]) / len(df)0.05948372615039282df = df[df.Fare < 100]
We can now plot the histogram of “Fare” column.
len(df[df.Fare > 100]) / len(df)0.05948372615039282df = df[df.Fare < 100]
Most of the ticket prices are less than 20 and numbers decrease as we go up to 100.
It is time to introduce 2D histograms which combine 2 different histograms on x-axis and y-axis. Thus, we are able to visualize the density of overlaps or concurrence.
len(df[df.Fare > 100]) / len(df)0.05948372615039282df = df[df.Fare < 100]
It seems like a scatter plot with regions instead of showing individual points. We have a grid that partitions fare-age combinations. Interactive plots of plotly allow you to see the range each partition represents as well as the number of points in those regions. The yellowish partitions contain the highest number of passengers. As the color gets darker, number of passengers that falls into the partitions decreases.
We can also visualize the histograms that constitute this density plot using marginal parameters.
fig = px.density_heatmap(df, x="Age", y="Fare",                         title="Density Map of Age and Fare",                         marginal_x="histogram",                         marginal_y="histogram",                         width=800, height=500)fig.show()
We are able to see both age and fare histograms in addition to the density plot.
As you may already know, the purpose of the titanic survival dataset is to predict whether a passenger survived based on the data given in the dataset. The features (class, age, gender, fare...) are used as independent variables to predict the target (survived) variable. Before implementing a machine learning model, we can use data visualizations to have an idea if certain features affect the survival rate.
Let’s distinguish the density plot of “Age” and “Fare” based on “survived” column using the facet_col parameter.
fig = px.density_heatmap(df, x="Age", y="Fare",       title="Density Map of Age and Fare Based on Survival",        facet_col="Survived")fig.show()
Density plots look similar but we can conclude that being in the yellowish area on the left plot decreases the chance of survival. For these two grids, the ratio of not-survived to survived passengers (183/66) are higher than the same ratio in the entire dataset (535/303).
df.Survived.value_counts()0    535 1    303 Name: Survived, dtype: int64
We have covered 2D histograms (density plots) with plotly. Of course, this is just a little of what can be done with this amazing library. There are many other plot types that we can dynamically create with plotly. Its syntax is easy to understand as well. I will try to cover more complex plots in the upcoming posts. You can also check the plotly documentation which I think is well-documented with many different examples. Just like any other topic, the best way to get familiar with plotly is to practice. Thus, I suggest creating lots of plots to sharpen your skills.
Thank you for reading. Please let me know if you have any feedback.