在 Plotly 直方图中,如何使每个动画帧在数据框中排成一行?
In a Plotly histogram, how to make each animation frame a row in the dataframe?
我有以下 pandas 数据框:
month stories comments comment_authors story_authors
0 2006-10 49 12 4 16
1 2007-02 564 985 192 163
2 2007-03 1784 4521 445 287
我正在尝试构建一个 Plotly 直方图,其中每个 stories
、comments
、comment_authors
和 [=16] 都有四个分类箱(x 轴) =] 列,计数(y 轴)是特定 month
(即特定行)的给定数量。然后,我尝试使用 animation_frame
和 animation_group
.
根据 Plotly Express 中的月份对直方图进行动画处理
例如,month=2006-10
的第一个直方图类似于:
50 | ____
45 | | |
40 | | |
35 | | |
30 | | |
25 | | |
20 | | |
15 | | | ____
10 | | | ____ | |
5 | | | | | ______ | |
0 ----------------------------------------------------
stories comments comment_authors story_authors
在下一个动画帧的直方图中,它将读取 stories
、comments
、comment_authors
、story_authors
列的值 month=2007-02
.
这可以在Plotly中构建吗?有没有比 px.Histogram
更好的数字,比如 px.Bar
?我试过将列放在 x 轴上并使用月份作为动画帧,但这会将列堆叠到直方图上的一个容器中并使用整个列的计数,而不是特定行的值。
histogram = dcc.Graph(figure=px.histogram(
df, x=['stories', 'comments', 'comment_authors', 'story_authors'],
animation_frame='month', animation_group='month'
))
无法使用您提供的数据绘制直方图。你能做的最好的是条形图,你可以用时间序列来制作它的动画。我已经修改了官方 reference 中的示例以适合您的数据。
import pandas as pd
import numpy as np
import io
data = '''
month stories comments comment_authors story_authors
0 2006-10 49 12 4 16
1 2007-02 564 985 192 163
2 2007-03 1784 4521 445 287
'''
df = pd.read_csv(io.StringIO(data), delim_whitespace=True)
df.set_index('month', inplace=True)
dfs = df.unstack().reset_index()
dfs.columns = ['category', 'month', 'value']
import plotly.express as px
fig = px.bar(dfs, x='category', y='value', color='category', animation_frame='month', range_y=[0,dfs['value'].max()])
fig.show()
@r-beginners 的回答是做到这一点的最佳方式,但我想分享如何手动完成,以防将来其他人发现这个问题(这样我的辛劳就不会白费).这是我在 @r-beginners 回答之前手动完成此操作的方式。
# build list of frames for animation
cols = ['stories', 'comments', 'comment_authors', 'story_authors']
frames = list(map(
lambda index: go.Frame(
data=[go.Bar(
x=cols,
y=list(map(lambda col: df.iloc[index][col], cols))
)]
), range(len(df.index))
))
# compute chart height
m = max(list(filter(
lambda m: not isinstance(m, str), list(df.max())
))) * 1.1
# compute animation steps for slider
steps = list(map(
lambda index: {
'args': [
[str(df.iloc[index]['month'])],
{
'frame': {'duration': 300, 'redraw': False},
'mode': 'immediate',
'transition': {'duration': 300}
}
],
'label': str(df.iloc[index]['month']),
'method': 'animate'
}, range(len(df.index))
))
# metadata for slider element
sliders_dict = {
"active": 0,
"yanchor": "top",
"xanchor": "left",
"currentvalue": {
"font": {"size": 20},
"prefix": "Month: ",
"visible": True,
"xanchor": "right"
},
"transition": {"duration": 300, "easing": "cubic-in-out"},
"pad": {"b": 10, "t": 50},
"len": 0.9,
"x": 0.1,
"y": 0,
"steps": steps
}
# histogram figure - actually a bar chart
histogram = dcc.Graph(id='counts-histogram', figure=go.Figure(
data=frames[0].data[0],
layout=go.Layout(
yaxis=dict(range=[0, m], autorange=False),
updatemenus=[
{
"buttons": [
{
"args": [None, {"frame": {"duration": 500, "redraw": False},
"fromcurrent": True, "transition": {"duration": 300,
"easing": "quadratic-in-out"}}],
"label": "Play",
"method": "animate"
},
{
"args": [[None], {"frame": {"duration": 0, "redraw": False},
"mode": "immediate",
"transition": {"duration": 0}}],
"label": "Pause",
"method": "animate"
}
],
"direction": "left",
"pad": {"r": 10, "t": 87},
"showactive": False,
"type": "buttons",
"x": 0.1,
"xanchor": "right",
"y": 0,
"yanchor": "top"
}
],
sliders = [sliders_dict]
),
frames=frames
))
我有以下 pandas 数据框:
month stories comments comment_authors story_authors
0 2006-10 49 12 4 16
1 2007-02 564 985 192 163
2 2007-03 1784 4521 445 287
我正在尝试构建一个 Plotly 直方图,其中每个 stories
、comments
、comment_authors
和 [=16] 都有四个分类箱(x 轴) =] 列,计数(y 轴)是特定 month
(即特定行)的给定数量。然后,我尝试使用 animation_frame
和 animation_group
.
例如,month=2006-10
的第一个直方图类似于:
50 | ____
45 | | |
40 | | |
35 | | |
30 | | |
25 | | |
20 | | |
15 | | | ____
10 | | | ____ | |
5 | | | | | ______ | |
0 ----------------------------------------------------
stories comments comment_authors story_authors
在下一个动画帧的直方图中,它将读取 stories
、comments
、comment_authors
、story_authors
列的值 month=2007-02
.
这可以在Plotly中构建吗?有没有比 px.Histogram
更好的数字,比如 px.Bar
?我试过将列放在 x 轴上并使用月份作为动画帧,但这会将列堆叠到直方图上的一个容器中并使用整个列的计数,而不是特定行的值。
histogram = dcc.Graph(figure=px.histogram(
df, x=['stories', 'comments', 'comment_authors', 'story_authors'],
animation_frame='month', animation_group='month'
))
无法使用您提供的数据绘制直方图。你能做的最好的是条形图,你可以用时间序列来制作它的动画。我已经修改了官方 reference 中的示例以适合您的数据。
import pandas as pd
import numpy as np
import io
data = '''
month stories comments comment_authors story_authors
0 2006-10 49 12 4 16
1 2007-02 564 985 192 163
2 2007-03 1784 4521 445 287
'''
df = pd.read_csv(io.StringIO(data), delim_whitespace=True)
df.set_index('month', inplace=True)
dfs = df.unstack().reset_index()
dfs.columns = ['category', 'month', 'value']
import plotly.express as px
fig = px.bar(dfs, x='category', y='value', color='category', animation_frame='month', range_y=[0,dfs['value'].max()])
fig.show()
@r-beginners 的回答是做到这一点的最佳方式,但我想分享如何手动完成,以防将来其他人发现这个问题(这样我的辛劳就不会白费).这是我在 @r-beginners 回答之前手动完成此操作的方式。
# build list of frames for animation
cols = ['stories', 'comments', 'comment_authors', 'story_authors']
frames = list(map(
lambda index: go.Frame(
data=[go.Bar(
x=cols,
y=list(map(lambda col: df.iloc[index][col], cols))
)]
), range(len(df.index))
))
# compute chart height
m = max(list(filter(
lambda m: not isinstance(m, str), list(df.max())
))) * 1.1
# compute animation steps for slider
steps = list(map(
lambda index: {
'args': [
[str(df.iloc[index]['month'])],
{
'frame': {'duration': 300, 'redraw': False},
'mode': 'immediate',
'transition': {'duration': 300}
}
],
'label': str(df.iloc[index]['month']),
'method': 'animate'
}, range(len(df.index))
))
# metadata for slider element
sliders_dict = {
"active": 0,
"yanchor": "top",
"xanchor": "left",
"currentvalue": {
"font": {"size": 20},
"prefix": "Month: ",
"visible": True,
"xanchor": "right"
},
"transition": {"duration": 300, "easing": "cubic-in-out"},
"pad": {"b": 10, "t": 50},
"len": 0.9,
"x": 0.1,
"y": 0,
"steps": steps
}
# histogram figure - actually a bar chart
histogram = dcc.Graph(id='counts-histogram', figure=go.Figure(
data=frames[0].data[0],
layout=go.Layout(
yaxis=dict(range=[0, m], autorange=False),
updatemenus=[
{
"buttons": [
{
"args": [None, {"frame": {"duration": 500, "redraw": False},
"fromcurrent": True, "transition": {"duration": 300,
"easing": "quadratic-in-out"}}],
"label": "Play",
"method": "animate"
},
{
"args": [[None], {"frame": {"duration": 0, "redraw": False},
"mode": "immediate",
"transition": {"duration": 0}}],
"label": "Pause",
"method": "animate"
}
],
"direction": "left",
"pad": {"r": 10, "t": 87},
"showactive": False,
"type": "buttons",
"x": 0.1,
"xanchor": "right",
"y": 0,
"yanchor": "top"
}
],
sliders = [sliders_dict]
),
frames=frames
))