Improving Your Data Visualizations with Stacked Bar Charts in Python | by Byron Dolon | Towards Data Science

Just looking at numbers on a table may make it difficult to identify trends in a dataset. Visualizing data makes it a lot easier for people to quickly understand key ideas. An important part of data visualization is choosing the right chart types based on the type of data you are analyzing.
Standard scatter charts, line charts, and bar charts are great for visualizing a wide variety of numerical and categorical data. You can improve on these basic charts by adding additional features that make it even easier for the end-user to understand the data.
In this piece, let’s take a look at how to create and customize stacked bar charts with the Plotly Express library in Python for data visualization. We’ll also use the Pandas library for some data pre-processing steps, so make sure you have these two packages installed already. Then, import the following and get ready to follow along on your own Jupyter notebook!
import pandas as pdimport plotly.express as pximport random
Let’s get to it!
First, let’s generate some sample data to use in our data analysis and visualizations. To do so, run the following code below.
expense_data = {    "Person": random.choices(["A", "B"], k=30),    "Amount": random.sample(range(100, 200), 10) + random.sample(range(0, 99), 10) + random.sample(range(49, 499), 10),    "Category": ["Groceries"] * 10 + ["Restaurant"] * 10 + ["Appliances"] * 10,    "Date": pd.to_datetime(pd.date_range('2020-01-01','2020-10-01', freq='MS').tolist() * 3)}df = pd.DataFrame(data=expense_data)
In this piece, we’ll be analyzing and visualizing some randomly generated personal expense data. The code should generate a Pandas DataFrame with 30 rows of expenses in three different categories over time.
The goal of this data analysis is to examine the spending per category every month and potentially identify trends occurring over time. As such, let’s use some Pandas to group the total spending per month together per category. You can do so using the two lines of code below.
df_grouped = df.groupby(by=[pd.Grouper(key="Date", freq="1M"), "Category"])["Amount"]df_grouped = df_grouped.sum().reset_index()
Now that our data has been processed to fit our initial question, we can dive straight into visualizing the data. The Plotly library makes clean-looking visualizations that have a bit more style than the standard graphs that you can create with Pandas (or matplotlib). Plotly Express takes it a step further and makes creating visualizations ridiculously easy. We’ll create our initial graph with just one line of code below.
fig = px.bar(df_grouped, x="Date", y="Amount", color="Category")fig.show()
The first input to the bar method is the grouped DataFrame we just created. Then, we pass the column names from our DataFrame into the x and y parameters of the bar method. Finally, to implement the stacked bar chart, all we need to do is pass the column name that we want to stack into the color parameter.
You can further customize the stacked bar chart by filling in the optional barmode parameter. You can see an example of this and the resulting chart below.
fig2 = px.bar(df_grouped, x="Date", y="Amount", color="Category", barmode="group")fig2.show()
Passing group as an argument to the barmode parameter gives us a graph like above, where the expense per category bars for each month are grouped side by side instead of being stacked vertically.
There are four possible options that you can pass into barmode: stack, group, overlay, and relative. As an example of what you might do during your exploratory data analysis phase, you could run the following code to take a look at all the different options for the bar graphs.
barmodes = ["stack", "group", "overlay", "relative"]for barmode in barmodes:    fig_bar = px.bar(df_grouped, x="Date", y="Amount", color="Category", barmode=barmode)    fig_bar.show()
Each of the bar mode options will display slightly different graphs. The “relative” bar mode will only be relevant when you have negative values, as this mode will cause Plotly to display the relevant categories with negative values below the axis.
You could potentially encapsulate the above code block into a function and then run it on your data as a part of your exploratory data analysis (EDA), where you could also figure out which of these graphs is most suited to the data you’re looking at. Then, once you’ve decided which bar mode works best for you, you could choose either just to only generate one graph or export the graphs to png from your notebook (which is a handy feature of Plotly Express).
As we take a look at a few more features you can do with bar charts, lets continue analyzing our sample data and compare the expense data per person over time. To do so, we’ll group the data again using the same groupby method as before.
df_people = df.groupby(by=[pd.Grouper(key="Date", freq="1M"), "Person"])["Amount"]df_people = df_people.sum().reset_index()
The resulting DataFrame will give us the total spending per person per month in our data set. We can now plug this DataFrame into the Plotly bar method as before but with one small addition.
fig_people = px.bar(df_people, x="Date", y="Amount", color="Person", barmode="stack", text="Amount")fig_people.show()
We can now clearly see which person spent more on each month with this graph. Since we’re dealing with financial data, it might be useful to have the amounts per category shown directly on the bar (instead of having to guess the rough amounts from the axis).
To do so, we set the text parameter in the bar method equal to the column we would like to show up as bar labels, which in this case was “Amount”. You could then potentially remove the y-axis from the graph, since it’s now redundant given the text labels directly on the columns.
We can explore one final feature with bar graphs in Plotly Express by analyzing the spending per category per person. We’ll group our data by category and person into a new DataFrame first by running the code below.
df_category = df.groupby(["Category", "Person"]).sum().reset_index()
Now, using this grouped DataFrame, we can use the same Plotly express bar method with the features we’ve explored so far, but with a few more additions.
fig_category = px.bar(df_category, x="Amount", y="Person", color="Category", text="Amount", orientation="h")fig_category = fig_category.update_traces(insidetextanchor="middle", texttemplate="$%{text}")fig_category = fig_category.update_xaxes(visible=False, showticklabels=False)fig_category.show()
First, you’ll see that we’ve created a horizontal bar chart instead of the vertical format we’ve been using before. All we had to do to implement this change was pass “h” to the orientation parameter in the bar method. Then, we also wanted to have text labels again, but to make sure that the text labels showed up in the middle of the bar labels, we’ll use the update_traces method and pass “middle” to the insidetextanchor parameter.
Also, we can set a custom format for the text labels by setting it in the texttemplate parameter in the update_traces method. We’ll simply add a dollar sign in front of our labels, so in this case we pass in "$%{text}", as in Plotly Express you can reference columns by using the percentage sign followed by the column name in brackets.
Finally, since we’ve already added a dollar sign to make the bar values very clear, we can go ahead and remove the axes with the “Amount” column values using the update_xaxes method and setting the visible and showticklabels parameters to “False”.
And that’s all!
I hope you found this very quick introduction to stacked bar charts with Plotly in Python useful for your data analysis. Using Plotly Express makes it really easy for you to just plug in a Pandas DataFrame and get straight away to visualizing your data with just a few lines of code.
Thank you again for reading! If you’re thinking about becoming a paying member on Medium, I would really appreciate it if you sign up using my referral link below! This would let directly receive a portion of your membership fees, so it would be a big help.
byrondolon.medium.com
More by me:- Check for a Substring in a Pandas DataFrame- Conditional Selection and Assignment With .loc in Pandas- 2 Easy Ways to Get Tables From a Website With Pandas- Top 4 Repositories on GitHub to Learn Pandas- Level Up Your Data Visualizations with Trend Lines in Python- Better Data Visualization with Dual Axis Graphs in Python