问题
I have a Dataframe
Date Category Sum
0 2019-06-03 "25M" 34
1 2019-06-03 "25M" 60
2 2019-06-03 "50M" 23
3 2019-06-04 "25M" 67
4 2019-06-05 "50M" -90
5 2019-06-05 "50M" 100
6 2019-06-06 "100M" 6
7 2019-06-07 "25M" -100
8 2019-06-08 "100M" 67
9 2019-06-09 "25M" 450
10 2019-06-10 "50M" 600
11 2019-06-11 "25M" -9
12 2019-07-12 "50M" 45
13 2019-07-13 "50M" 67
14 2019-07-14 "100M" 130
15 2019-07-14 "50M" 45
16 2019-07-15 "100M" 100
17 2019-07-16 "25M" -90
18 2019-07-17 "25M" 700
19 2019-07-18 "25M" -9
I want to create a plotly graph showing the addition of "Sum" for different "Category" on Every described date, but want to remove dates, if they don't have any data.
Code
df["Date"]=pd.to_datetime(df["Date"], format=("%Y%m%d"))
df=df.sort_values(["Date","Category","Sum"],ascending=False)
df=round(df.groupby(["Date","Category"]).agg({"Sum":"sum"}).reset_index(),1)
fig = px.bar(df, x=df["Date"] , y='Sum',barmode="group",color="Category")
fig.update_xaxes(
rangeslider_visible=True,
rangeselector=dict(
buttons=list([
dict(count=1, label="day", step="day", stepmode="todate"),
dict(count=24, label="montly", step="month", stepmode="todate"),
dict(count=1, label="year", step="year", stepmode="todate"),
dict(step="all")
])
))
fig.show()
I am getting graph like this but I want to remove the empty Dates from the plotly graph
回答1:
This problem comes from the fact that plotly interprets your 'Date'
as dates, creates a continuous period between the oldest and newest timestamp, effectively showing dates with no associated data as gaps. One solution is to take the first and last date in your date column, and make a complete list of dates in that period, and then sort out which dates do not have any observations, and stor that in a variable named dt_breaks
. Then, at last, you can include those dates in:
fig.update_xaxes(
rangebreaks=[dict(values=dt_breaks)] # hide dates with no values
)
This will drop those dates in your visualization, and keep the x-values formatted as dates so that you can subset the data using your buttons:
And here, as you already know, is the same visualization without rangebreaks=[dict(values=dt_breaks)]
:
To make this work as simply as possible, I rearranged the date column using df=df.sort_values(["Date","Category","Sum"],ascending=True)
instead of df=df.sort_values(["Date","Category","Sum"],ascending=False)
as in your original code snippet
Complete code:
import pandas as pd
import plotly.express as px
df = pd.DataFrame({'Date': {0: '2019-06-03',
1: '2019-06-03',
2: '2019-06-03',
3: '2019-06-04',
4: '2019-06-05',
5: '2019-06-05',
6: '2019-06-06',
7: '2019-06-07',
8: '2019-06-08',
9: '2019-06-09',
10: '2019-06-10',
11: '2019-06-11',
12: '2019-07-12',
13: '2019-07-13',
14: '2019-07-14',
15: '2019-07-14',
16: '2019-07-15',
17: '2019-07-16',
18: '2019-07-17',
19: '2019-07-18'},
'Category': {0: '"25M"',
1: '"25M"',
2: '"50M"',
3: '"25M"',
4: '"50M"',
5: '"50M"',
6: '"100M"',
7: '"25M"',
8: '"100M"',
9: '"25M"',
10: '"50M"',
11: '"25M"',
12: '"50M"',
13: '"50M"',
14: '"100M"',
15: '"50M"',
16: '"100M"',
17: '"25M"',
18: '"25M"',
19: '"25M"'},
'Sum': {0: 34,
1: 60,
2: 23,
3: 67,
4: -90,
5: 100,
6: 6,
7: -100,
8: 67,
9: 450,
10: 600,
11: -9,
12: 45,
13: 67,
14: 130,
15: 45,
16: 100,
17: -90,
18: 700,
19: -9}})
df["Date"]=pd.to_datetime(df["Date"], format=("%Y-%m-%d"))
df=df.sort_values(["Date","Category","Sum"],ascending=True)
df=round(df.groupby(["Date","Category"]).agg({"Sum":"sum"}).reset_index(),1)
dt_all = pd.date_range(start=df['Date'].iloc[0],end=df['Date'].iloc[-1])
dt_obs = [d.strftime("%Y-%m-%d") for d in df['Date']]
dt_breaks = [d for d in dt_all.strftime("%Y-%m-%d").tolist() if not d in dt_obs]
df=df.set_index('Date')
#fig = px.bar(df, x=df.index.strftime("%Y/%m/%d") , y='Sum',barmode="group",color="Category")
fig = px.bar(df, x=df.index , y='Sum',barmode="group",color="Category")
fig.update_xaxes(
#rangebreaks=[dict(values=dt_breaks)] # hide dates with no values
)
fig.update_xaxes(
rangeslider_visible=True,
rangeselector=dict(
buttons=list([
dict(count=1, label="day", step="day", stepmode="todate"),
dict(count=24, label="montly", step="month", stepmode="todate"),
dict(count=1, label="year", step="year", stepmode="todate"),
dict(step="all")
])
))
fig.show()
来源:https://stackoverflow.com/questions/61895282/plotly-how-to-remove-empty-dates-from-x-axis