admin管理员组文章数量:1303529
Code
import pandas as pd
import streamlit as st
import plotly.express
import plotly
data = {
'2024-01-31' : 1044,
'2024-02-29' : 2310,
'2024-03-31' : 518,
'2024-04-30' : -1959,
'2024-05-31' : 0,
'2024-06-30' : -1010,
'2024-07-31' : 1500,
'2024-08-31' : -15459,
'2024-09-30' : -14153,
'2024-10-31' : -12604,
'2024-11-30' : -5918,
'2024-12-31' : -3897
}
df = pd.DataFrame(data.items(), columns=['date', 'value'])
fig = plotly.express.bar(data_frame=df, x='date', y='value')
st.plotly_chart(fig)
Issue
In this screenshot, the mouse is hovering over the rightmost bar.
The hover label says Dec 31, 2024
, which is expected.
Note that the x-axis label says Jan 2025
.
Workaround
Here's one approach to a workaround:
df['date'] = pd.to_datetime(df['date']).dt.to_period('M').dt.to_timestamp()
Code:
import pandas as pd
import streamlit as st
import plotly.express
import plotly
data = {
'2024-01-31' : 1044,
'2024-02-29' : 2310,
'2024-03-31' : 518,
'2024-04-30' : -1959,
'2024-05-31' : 0,
'2024-06-30' : -1010,
'2024-07-31' : 1500,
'2024-08-31' : -15459,
'2024-09-30' : -14153,
'2024-10-31' : -12604,
'2024-11-30' : -5918,
'2024-12-31' : -3897
}
df = pd.DataFrame(data.items(), columns=['date', 'value'])
df['date'] = pd.to_datetime(df['date']).dt.to_period('M').dt.to_timestamp()
fig = plotly.express.bar(data_frame=df, x='date', y='value')
st.plotly_chart(fig)
Now the x-axis labels match the data bar months:
Notes
The workaround here basically changes each date value from being the month-end to the first of the month.
So, instead of this
>>> df
date value
0 2024-01-31 1044
1 2024-02-29 2310
2 2024-03-31 518
3 2024-04-30 -1959
4 2024-05-31 0
5 2024-06-30 -1010
6 2024-07-31 1500
7 2024-08-31 -15459
8 2024-09-30 -14153
9 2024-10-31 -12604
10 2024-11-30 -5918
11 2024-12-31 -3897
we have this:
>>> df
date value
0 2024-01-01 1044
1 2024-02-01 2310
2 2024-03-01 518
3 2024-04-01 -1959
4 2024-05-01 0
5 2024-06-01 -1010
6 2024-07-01 1500
7 2024-08-01 -15459
8 2024-09-01 -14153
9 2024-10-01 -12604
10 2024-11-01 -5918
11 2024-12-01 -3897
The change is made with this line:
df['date'] = pd.to_datetime(df['date']).dt.to_period('M').dt.to_timestamp()
Question
Is this the recommended approach to resolving this issue? Or is there a more idiomatic method using plotly?
Code
import pandas as pd
import streamlit as st
import plotly.express
import plotly
data = {
'2024-01-31' : 1044,
'2024-02-29' : 2310,
'2024-03-31' : 518,
'2024-04-30' : -1959,
'2024-05-31' : 0,
'2024-06-30' : -1010,
'2024-07-31' : 1500,
'2024-08-31' : -15459,
'2024-09-30' : -14153,
'2024-10-31' : -12604,
'2024-11-30' : -5918,
'2024-12-31' : -3897
}
df = pd.DataFrame(data.items(), columns=['date', 'value'])
fig = plotly.express.bar(data_frame=df, x='date', y='value')
st.plotly_chart(fig)
Issue
In this screenshot, the mouse is hovering over the rightmost bar.
The hover label says Dec 31, 2024
, which is expected.
Note that the x-axis label says Jan 2025
.
Workaround
Here's one approach to a workaround:
df['date'] = pd.to_datetime(df['date']).dt.to_period('M').dt.to_timestamp()
Code:
import pandas as pd
import streamlit as st
import plotly.express
import plotly
data = {
'2024-01-31' : 1044,
'2024-02-29' : 2310,
'2024-03-31' : 518,
'2024-04-30' : -1959,
'2024-05-31' : 0,
'2024-06-30' : -1010,
'2024-07-31' : 1500,
'2024-08-31' : -15459,
'2024-09-30' : -14153,
'2024-10-31' : -12604,
'2024-11-30' : -5918,
'2024-12-31' : -3897
}
df = pd.DataFrame(data.items(), columns=['date', 'value'])
df['date'] = pd.to_datetime(df['date']).dt.to_period('M').dt.to_timestamp()
fig = plotly.express.bar(data_frame=df, x='date', y='value')
st.plotly_chart(fig)
Now the x-axis labels match the data bar months:
Notes
The workaround here basically changes each date value from being the month-end to the first of the month.
So, instead of this
>>> df
date value
0 2024-01-31 1044
1 2024-02-29 2310
2 2024-03-31 518
3 2024-04-30 -1959
4 2024-05-31 0
5 2024-06-30 -1010
6 2024-07-31 1500
7 2024-08-31 -15459
8 2024-09-30 -14153
9 2024-10-31 -12604
10 2024-11-30 -5918
11 2024-12-31 -3897
we have this:
>>> df
date value
0 2024-01-01 1044
1 2024-02-01 2310
2 2024-03-01 518
3 2024-04-01 -1959
4 2024-05-01 0
5 2024-06-01 -1010
6 2024-07-01 1500
7 2024-08-01 -15459
8 2024-09-01 -14153
9 2024-10-01 -12604
10 2024-11-01 -5918
11 2024-12-01 -3897
The change is made with this line:
df['date'] = pd.to_datetime(df['date']).dt.to_period('M').dt.to_timestamp()
Question
Is this the recommended approach to resolving this issue? Or is there a more idiomatic method using plotly?
Share Improve this question asked Feb 4 at 16:54 dharmatechdharmatech 9,53710 gold badges48 silver badges105 bronze badges2 Answers
Reset to default 2The dates you're using are all the last days of each month (e.g., 2024-01-31, 2024-02-29, etc.), which can cause the x-axis to shift slightly, especially when formatting. Try adjusting the date to the month start instead.
import pandas as pd
import plotly.express as px
data = {
'2024-01-31' : 1044,
'2024-02-29' : 2310,
'2024-03-31' : 518,
'2024-04-30' : -1959,
'2024-05-31' : 0,
'2024-06-30' : -1010,
'2024-07-31' : 1500,
'2024-08-31' : -15459,
'2024-09-30' : -14153,
'2024-10-31' : -12604,
'2024-11-30' : -5918,
'2024-12-31' : -3897
}
df = pd.DataFrame(data.items(), columns=['date', 'value'])
# convert to datetime
df['date'] = pd.to_datetime(df['date'])
# Adjust the dates to the first day of the month
df['date'] = df['date'].dt.to_period('M').dt.start_time
fig = px.bar(df, x='date', y='value')
fig.show()
You can also try the following if you want to preserve the hover data but update the x-axis labels
# Convert 'date' column to datetime format
df['date'] = pd.to_datetime(df['date'])
# Create the bar plot
fig = px.bar(df, x='date', y='value')
# Store original 'date' column in customdata for hover
fig.update_traces(
customdata=df['date'] # Store the original date for hover text
)
# Update x-axis to show only month and year
fig.update_xaxes(
tickvals=df['date'],
ticktext=df['date'].dt.strftime('%b %Y') # Format: abbreviated month and full year (e.g., Jan 2024)
)
# Customize hover template to show the original date (from customdata)
fig.update_traces(
hovertemplate="<b>Date:</b> %{customdata|%b %d, %Y}<br><b>Value:</b> %{y}<extra></extra>"
)
fig.show()
The first proposal allows specifying the range of the x-axis, so setting range_x
will change the scale of the x-axis that is automatically adjusted. This explanation can be found here.
import plotly.express as px
fig = px.bar(data_frame=df, x='date', y='value', range_x=['2024-01-31','2024-12-31'])
fig.show()
My second suggestion is to customize the display of the x-axis. To make it equivalent to the x-axis in the question, change the display criteria to 'M2'. There is a ticklabelmode, and there is an instant and a period. Changing this to 'period' will set the string between the scales. See here for details. The rest is adjusting the position of the scale. This adjustment needs to be adjusted depending on the environment in which it will be used.
fig = px.bar(data_frame=df, x='date', y='value')
fig.update_xaxes(dtick="M2", tickformat="%b %Y", ticklabelmode="period", ticklabelshift=40)
fig.show()
本文标签: pythonplotly xaxis label is offset by one monthStack Overflow
版权声明:本文标题:python - plotly x-axis label is offset by one month - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741751870a2395881.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论