I have data of ~3 years organised by month and year. I want to plot this data as a bar chart by month and year, with the month as the x-axis and the year as a trace. The problem is that the data starts in September 2018, so the first month to be plotted is September, but I want it to be January. I've tried to do that but then the years are in decreasing order, which I don't want either. Here is a code example.
import datetime
import pandas as pd
import plotly.graph_objects as go
import random
df = pd.DataFrame({})
numdays = 1000
base = datetime.datetime.today()
date_list = [base - datetime.timedelta(days=x) for x in range(numdays)]
price = [random.randint(1,10) for i in range(numdays)]
df['price'] = price
df.index = date_list
df = df.resample('MS').sum()
df['month'] = df.index.month_name()
df['month number'] = df.index.month
df['year'] = df.index.year
year_list = df['year'].unique().tolist()
fig = go.Figure()
for year in year_list:
df_aux = df[df.year==year]
df_aux = df_aux.sort_values(by=['month number'])
fig.add_trace(go.Bar(x=df_aux.month, y=df_aux['price'], \
name=year))
fig.show()
This is what I get, but it starts in September and I want it to be January:

Using this reference for categorical axes from plotly, I was able to use the categoryorder and set the catergoryarray, which allows you to set the list of the order that you want to use for your axis.
From the documentation/reference:
Whether using Plotly Express or not, categories can be sorted alphabetically or by value using the categoryorder attribute:
and also:
This example shows how to control category order when using plotly.graph_objects by defining categoryorder to "array" to derive the ordering from the attribute categoryarray.
The line of code that I added was:
fig.update_xaxes(categoryorder='array', categoryarray= ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'])
and this gave an output which looked like this:

The complete code:
import datetime
import pandas as pd
import plotly.graph_objects as go
import random
df = pd.DataFrame({})
numdays = 1000
base = datetime.datetime.today()
date_list = [base - datetime.timedelta(days=x) for x in range(numdays)]
price = [random.randint(1,10) for i in range(numdays)]
df['price'] = price
df.index = date_list
df = df.resample('MS').sum()
df['month'] = df.index.month_name()
df['month number'] = df.index.month
df['year'] = df.index.year
year_list = df['year'].unique().tolist()
fig = go.Figure()
for year in year_list:
df_aux = df[df.year==year]
df_aux = df_aux.sort_values(by=['month number'])
fig.add_trace(go.Bar(x=df_aux.month, y=df_aux['price'], \
name=year))
fig.update_xaxes(categoryorder='array', categoryarray= ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'])
fig.show()
You can define category_orders for month like this:
import datetime
import pandas as pd
import plotly.graph_objects as go
import random
df = pd.DataFrame({})
numdays = 1000
base = datetime.datetime.today()
date_list = [base - datetime.timedelta(days=x) for x in range(numdays)]
price = [random.randint(1,10) for i in range(numdays)]
df['price'] = price
df.index = date_list
df = df.resample('MS').sum()
df['month'] = df.index.month_name()
df['year'] = df.index.year
df['year'] = pd.Categorical(df['year'])
fig = px.bar(df,x='month', y='price',
category_orders={'month':['January', 'February', 'March',
'April', 'May', 'June', 'July',
'August', 'September', 'October', 'November', 'December']},
color='year',barmode="group")
fig.show()

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With