Bar Charts in Python
How to make Bar Charts in Python with Plotly.
Plotly Studio: Transform any dataset into an interactive data application in minutes with AI. Try Plotly Studio now.
Bar chart with Plotly Express¶
Plotly Express is the easy-to-use, high-level interface to Plotly, which operates on a variety of types of data and produces easy-to-style figures.
With px.bar, each row of the DataFrame is represented as a rectangular mark. To aggregate multiple data points into the same rectangular mark, please refer to the histogram documentation.
In the example below, there is only a single row of data per year, so a single bar is displayed per year.
import plotly.express as px
data_canada = px.data.gapminder().query("country == 'Canada'")
fig = px.bar(data_canada, x='year', y='pop')
fig.show()
Bar charts with Long Format Data¶
Long-form data has one row per observation, and one column per variable. This is suitable for storing and displaying multivariate data i.e. with dimension greater than 2. This format is sometimes called "tidy".
To learn more about how to provide a specific form of column-oriented data to 2D-Cartesian Plotly Express functions such as px.bar, see the Plotly Express Wide-Form Support in Python
documentation.
For detailed column-input-format documentation, see the Plotly Express Arguments documentation.
import plotly.express as px
long_df = px.data.medals_long()
fig = px.bar(long_df, x="nation", y="count", color="medal", title="Long-Form Input")
fig.show()
long_df
Bar charts with Wide Format Data¶
Wide-form data has one row per value of one of the first variable, and one column per value of the second variable. This is suitable for storing and displaying 2-dimensional data.
import plotly.express as px
wide_df = px.data.medals_wide()
fig = px.bar(wide_df, x="nation", y=["gold", "silver", "bronze"], title="Wide-Form Input")
fig.show()
wide_df
Bar charts in Dash¶
Dash is the best way to build analytical apps in Python using Plotly figures. To run the app below, run pip install dash, click "Download" to get the code and run python app.py.
Get started with the official Dash docs and learn how to effortlessly style & publish apps like this with Dash Enterprise or Plotly Cloud.
Sign up for Dash Club → Free cheat sheets plus updates from Chris Parmer and Adam Schroeder delivered to your inbox every two months. Includes tips and tricks, community apps, and deep dives into the Dash architecture. Join now.
Colored Bars¶
The bar plot can be customized using keyword arguments, for example to use continuous color, as below, or discrete color, as above.
import plotly.express as px
df = px.data.gapminder().query("country == 'Canada'")
fig = px.bar(df, x='year', y='pop',
hover_data=['lifeExp', 'gdpPercap'], color='lifeExp',
labels={'pop':'population of Canada'}, height=400)
fig.show()
import plotly.express as px
df = px.data.gapminder().query("continent == 'Oceania'")
fig = px.bar(df, x='year', y='pop',
hover_data=['lifeExp', 'gdpPercap'], color='country',
labels={'pop':'population of Oceania'}, height=400)
fig.show()
Stacked vs Grouped Bars¶
When several rows share the same value of x (here Female or Male), the rectangles are stacked on top of one another by default.
import plotly.express as px
df = px.data.tips()
fig = px.bar(df, x="sex", y="total_bill", color='time')
fig.show()
The default stacked bar chart behavior can be changed to grouped (also known as clustered) using the barmode argument:
import plotly.express as px
df = px.data.tips()
fig = px.bar(df, x="sex", y="total_bill",
color='smoker', barmode='group',
height=400)
fig.show()
Aggregating into Single Colored Bars¶
As noted above px.bar() will result in one rectangle drawn per row of input. This can sometimes result in a striped look as in the examples above. To combine these rectangles into one per color per position, you can use px.histogram(), which has its own detailed documentation page.
px.barandpx.histogramare designed to be nearly interchangeable in their call signatures, so as to be able to switch between aggregated and disaggregated bar representations.
import plotly.express as px
df = px.data.tips()
fig = px.histogram(df, x="sex", y="total_bill",
color='smoker', barmode='group',
height=400)
fig.show()
px.histogram() will aggregate y values by summing them by default, but the histfunc argument can be used to set this to avg to create what is sometimes called a "barplot" which summarizes the central tendency of a dataset, rather than visually representing the totality of the dataset.
Warning: when using
histfuncs other than"sum"or"count"it can be very misleading to use abarmodeother than"group", as stacked bars in effect represent the sum of the bar heights, and summing averages is rarely a reasonable thing to visualize.
import plotly.express as px
df = px.data.tips()
fig = px.histogram(df, x="sex", y="total_bill",
color='smoker', barmode='group',
histfunc='avg',
height=400)
fig.show()
Bar Charts with Text¶
New in v5.5
You can add text to bars using the text_auto argument. Setting it to True will display the values on the bars, and setting it to a d3-format formatting string will control the output format.
import plotly.express as px
df = px.data.medals_long()
fig = px.bar(df, x="medal", y="count", color="nation", text_auto=True)
fig.show()
The text argument can be used to display arbitrary text on the bars:
import plotly.express as px
df = px.data.medals_long()
fig = px.bar(df, x="medal", y="count", color="nation", text="nation")
fig.show()
By default, Plotly will scale and rotate text labels to maximize the number of visible labels, which can result in a variety of text angles and sizes and positions in the same figure. The textfont, textposition and textangle trace attributes can be used to control these.
Here is an example of the default behavior:
import plotly.express as px
df = px.data.gapminder().query("continent == 'Europe' and year == 2007 and pop > 2.e6")
fig = px.bar(df, y='pop', x='country', text_auto='.2s',
title="Default: various text sizes, positions and angles")
fig.show()
Here is the same data with less variation in text formatting. Note that textfont_size will set the maximum size. The layout.uniformtext attribute can be used to guarantee that all text labels are the same size. See the documentation on text and annotations for details.
The cliponaxis attribute is set to False in the example below to ensure that the outside text on the tallest bar is allowed to render outside of the plotting area.
import plotly.express as px
df = px.data.gapminder().query("continent == 'Europe' and year == 2007 and pop > 2.e6")
fig = px.bar(df, y='pop', x='country', text_auto='.2s',
title="Controlled text sizes, positions and angles")
fig.update_traces(textfont_size=12, textangle=0, textposition="outside", cliponaxis=False)
fig.show()
Pattern Fills¶
New in v5.0
Bar charts afford the use of patterns (also known as hatching or texture) in addition to color:
import plotly.express as px
df = px.data.medals_long()
fig = px.bar(df, x="medal", y="count", color="nation",
pattern_shape="nation", pattern_shape_sequence=[".", "x", "+"])
fig.show()
Facetted subplots¶
Use the keyword arguments facet_row (resp. facet_col) to create facetted subplots, where different rows (resp. columns) correspond to different values of the dataframe column specified in facet_row.
import plotly.express as px
df = px.data.tips()
fig = px.bar(df, x="sex", y="total_bill", color="smoker", barmode="group",
facet_row="time", facet_col="day",
category_orders={"day": ["Thur", "Fri", "Sat", "Sun"],
"time": ["Lunch", "Dinner"]})
fig.show()