使用Dash Plotly绘制带有独立颜色图例的条形图。

huangapple go评论88阅读模式
英文:

Plot bar chart with separate color legend - dash Plotly

问题

我尝试使用Dash制作柱状图来绘制特定值,但使用单独的列来映射颜色。使用以下代码,我正在绘制日期作为与下拉菜单条相对应的柱状图。

是否可能保持日期作为x轴,但使用DOW(星期几)作为离散颜色映射?我将附上当前的输出。日期被绘制出来,但存在一些问题。

  1. 下拉菜单中每个日期的字符串格式不是日期时间格式。

  2. 颜色映射与星期几不匹配。

  1. import dash
  2. from dash import dcc
  3. from dash import html
  4. from dash.dependencies import Input, Output
  5. import dash_bootstrap_components as dbc
  6. import plotly.express as px
  7. import plotly.graph_objs as go
  8. import pandas as pd
  9. from datetime import datetime as dt
  10. # 你的数据处理部分...
  11. # 创建Dash应用
  12. app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
  13. # 定义布局
  14. app.layout = dbc.Container([
  15. dbc.Row([
  16. dbc.Col(html.Div(filter_box, className="bg-secondary h-100"), width=2),
  17. dbc.Col([
  18. dbc.Row([
  19. dbc.Col(dcc.Graph(id='date-bar-chart'),
  20. ),
  21. ]),
  22. ], width=5),
  23. ])
  24. ], fluid=True)
  25. # 回调函数
  26. @app.callback(
  27. Output('date-bar-chart', 'figure'),
  28. [Input("DATE", "value"),
  29. ])
  30. def date_chart(date):
  31. # 你的绘图部分...
  32. if __name__ == '__main__':
  33. app.run_server(debug=True, port=8051)

你的问题主要是关于日期的格式和颜色映射,你需要对日期格式进行调整,并将DOW用作颜色映射。如有需要,你可以在回调函数中修改数据和布局以满足你的需求。

英文:

I'm trying to plot certain values using dash as a bar chart but use a separate column to map the colors. Using below, I'm plotting dates as a bar-chart that corresponds to a drop down bar.

Is it possible to keep the dates as the x-axis but use DOW (day of the week) as a discrete color map? I'll attach the current output below. The dates get plotted but there are a few issues.

  1. The string formatting for each date in the dropdown isn't in date time

  2. The color map isn't sequenced to the day of the week

    1. import dash
    2. from dash import dcc
    3. from dash import html
    4. from dash.dependencies import Input, Output
    5. import dash_bootstrap_components as dbc
    6. import plotly.express as px
    7. import plotly.graph_objs as go
    8. import pandas as pd
    9. from datetime import datetime as dt
    10. df = pd.DataFrame({
    11. 'Type': ['A','B','B','B','C','C','D','E','E','E','E','F','F','F'],
    12. })
    13. N = 30
    14. df = pd.concat([df] * N, ignore_index=True)
    15. df['TIMESTAMP'] = pd.date_range(start='2022/01/01 07:30', end='2022/01/30 08:30', periods=len(df))
    16. df['TIMESTAMP'] = pd.to_datetime(df['TIMESTAMP'], dayfirst = True).sort_values()
    17. df['DATE'], df['TIME'] = zip(*[(d.date(), d.time()) for d in df['TIMESTAMP']])
    18. df['DATE'] = pd.to_datetime(df['DATE'])
    19. df = df.sort_values(by = 'DATE')
    20. df['DOW'] = df['DATE'].dt.weekday
    21. df = df.sort_values('DOW').reset_index(drop=True)
    22. df['DOW'] = df['DATE'].dt.day_name()
    23. external_stylesheets = [dbc.themes.SPACELAB, dbc.icons.BOOTSTRAP]
    24. app = dash.Dash(__name__, external_stylesheets = external_stylesheets)
    25. filter_box = html.Div(children=[
    26. html.Div(children=[
    27. html.Label('Day of the week:', style={'paddingTop': '2rem'}),
    28. dcc.Dropdown(
    29. id='DATE',
    30. options=[
    31. {'label': x, 'value': x} for x in df['DATE'].unique()
    32. ],
    33. value=df['DATE'].unique(),
    34. multi=True
    35. ),
    36. ], className="four columns",
    37. style={'padding':'2rem', 'margin':'1rem'} )
    38. ])
    39. app.layout = dbc.Container([
    40. dbc.Row([
    41. dbc.Col(html.Div(filter_box, className="bg-secondary h-100"), width=2),
    42. dbc.Col([
    43. dbc.Row([
    44. dbc.Col(dcc.Graph(id = 'date-bar-chart'),
    45. ),
    46. ]),
    47. ], width=5),
    48. ])
    49. ], fluid=True)
    50. @app.callback(
    51. Output('date-bar-chart', 'figure'),
    52. [Input("DATE", "value"),
    53. ])
    54. def date_chart(date):
    55. dff = df[df['DATE'].isin(date)]
    56. count = dff['DATE'].value_counts()
    57. data = px.bar(x = count.index,
    58. y = count.values,
    59. #color = dff['DOW'],
    60. )
    61. layout = go.Layout(title = 'Date')
    62. fig = go.Figure(data = data, layout = layout)
    63. return fig
    64. if __name__ == '__main__':
    65. app.run_server(debug=True, port = 8051)

使用Dash Plotly绘制带有独立颜色图例的条形图。

答案1

得分: 2

不确定为什么您想要将DATE用作下拉菜单,但我认为您应该将其更改为字符串,然后将其传递给dcc.Dropdown。用以前的方式添加color_discrete_map,我认为您可以将代码修改如下:

  1. import dash
  2. from dash import dcc
  3. from dash import html
  4. from dash.dependencies import Input, Output
  5. import dash_bootstrap_components as dbc
  6. import plotly.express as px
  7. import plotly.graph_objs as go
  8. import pandas as pd
  9. from datetime import datetime as dt
  10. from dash.exceptions import PreventUpdate
  11. df = pd.DataFrame({
  12. 'Type': ['A', 'B', 'B', 'B', 'C', 'C', 'D', 'E', 'E', 'E', 'E', 'F', 'F', 'F'],
  13. })
  14. N = 30
  15. df = pd.concat([df] * N, ignore_index=True)
  16. df['TIMESTAMP'] = pd.date_range(start='2022/01/01 07:30', end='2022/01/30 08:30', periods=len(df))
  17. df['TIMESTAMP'] = pd.to_datetime(df['TIMESTAMP'], dayfirst=True).sort_values()
  18. df['DATE'], df['TIME'] = zip(*[(d.date(), d.time()) for d in df['TIMESTAMP']])
  19. df['DATE'] = pd.to_datetime(df['DATE'], format='%Y-%m-%d')
  20. df = df.sort values(by='DATE')
  21. df['DOW'] = df['DATE'].dt.weekday
  22. df = df.sort_values('DOW').reset_index(drop=True)
  23. df['DOW'] = df['DATE'].dt.day_name()
  24. df['DATE'] = df['DATE'].astype(str)
  25. df['Color'] = df['DOW'].map(dict(zip(df['DOW'].unique(), px.colors.qualitative.Plotly[:len(df['DOW'].unique())]))
  26. Color = df['Color'].unique()
  27. Category = df['DOW'].unique()
  28. Color = df['Color'].unique()
  29. Category = df['DOW'].unique()
  30. cats = dict(zip(Category, Color))
  31. external_stylesheets = [dbc.themes.SPACELAB, dbc.icons.BOOTSTRAP]
  32. app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
  33. filter_box = html.Div(children=[
  34. html.Div(children=[
  35. html.Label('Day of the week:', style={'paddingTop': '2rem'}),
  36. dcc.Dropdown(
  37. id='DATE',
  38. options=[
  39. {'label': x, 'value': x} for x in df['DATE'].unique()
  40. ],
  41. value=df['DATE'].unique(),
  42. multi=True
  43. ),
  44. ], className="four columns",
  45. style={'padding': '2rem', 'margin': '1rem'})
  46. ])
  47. app.layout = dbc.Container([
  48. dbc.Row([
  49. dbc.Col(html.Div(filter_box, className="bg-secondary h-100"), width=2),
  50. dbc.Col([
  51. dbc.Row([
  52. dbc.Col(dcc.Graph(id='date-bar-chart'),
  53. ),
  54. ]),
  55. ], width=5),
  56. ])
  57. ], fluid=True)
  58. @app.callback(
  59. Output('date-bar-chart', 'figure'),
  60. [Input("DATE", "value"),
  61. ])
  62. def date_chart(date):
  63. if date:
  64. dff = df[df['DATE'].isin(date)]
  65. count = dff.groupby(['DATE', "DOW"])['DATE'].count().reset_index(name='counts')
  66. data = px.bar(x=count['DATE'],
  67. y=count['counts'],
  68. color=count['DOW'],
  69. color_discrete_map=cats,
  70. )
  71. layout = go.Layout(title='Date')
  72. fig = go.Figure(data=data, layout=layout)
  73. return fig
  74. else:
  75. raise PreventUpdate
  76. if __name__ == '__main__':
  77. app.run_server(debug=False, port=8051)
  78. 我在`callback`中使用了`groupby`来返回新的数据框然后使用它来制作图表希望这有所帮助
  79. <details>
  80. <summary>英文:</summary>
  81. Not sure why do you want to use `DATE` as Dropdown but I think you should change it to string and then pass it to `dcc.Dropdown`. Used the previous way to add `color_discrete_map` I think you can revise your code as below:
  82. import dash
  83. from dash import dcc
  84. from dash import html
  85. from dash.dependencies import Input, Output
  86. import dash_bootstrap_components as dbc
  87. import plotly.express as px
  88. import plotly.graph_objs as go
  89. import pandas as pd
  90. from datetime import datetime as dt
  91. from dash.exceptions import PreventUpdate
  92. df = pd.DataFrame({
  93. &#39;Type&#39;: [&#39;A&#39;,&#39;B&#39;,&#39;B&#39;,&#39;B&#39;,&#39;C&#39;,&#39;C&#39;,&#39;D&#39;,&#39;E&#39;,&#39;E&#39;,&#39;E&#39;,&#39;E&#39;,&#39;F&#39;,&#39;F&#39;,&#39;F&#39;],
  94. })
  95. N = 30
  96. df = pd.concat([df] * N, ignore_index=True)
  97. df[&#39;TIMESTAMP&#39;] = pd.date_range(start=&#39;2022/01/01 07:30&#39;, end=&#39;2022/01/30 08:30&#39;, periods=len(df))
  98. df[&#39;TIMESTAMP&#39;] = pd.to_datetime(df[&#39;TIMESTAMP&#39;], dayfirst = True).sort_values()
  99. df[&#39;DATE&#39;], df[&#39;TIME&#39;] = zip(*[(d.date(), d.time()) for d in df[&#39;TIMESTAMP&#39;]])
  100. df[&#39;DATE&#39;] = pd.to_datetime(df[&#39;DATE&#39;],format=&#39;%Y-%m-%d&#39;)
  101. df = df.sort_values(by = &#39;DATE&#39;)
  102. df[&#39;DOW&#39;] = df[&#39;DATE&#39;].dt.weekday
  103. df = df.sort_values(&#39;DOW&#39;).reset_index(drop=True)
  104. df[&#39;DOW&#39;] = df[&#39;DATE&#39;].dt.day_name()
  105. df[&#39;DATE&#39;] = df[&#39;DATE&#39;].astype(str)
  106. df[&#39;Color&#39;] = df[&#39;DOW&#39;].map(dict(zip(df[&#39;DOW&#39;].unique(),
  107. px.colors.qualitative.Plotly[:len(df[&#39;DOW&#39;].unique())])))
  108. Color = df[&#39;Color&#39;].unique()
  109. Category = df[&#39;DOW&#39;].unique()
  110. Color = df[&#39;Color&#39;].unique()
  111. Category = df[&#39;DOW&#39;].unique()
  112. cats = dict(zip(Category,Color))
  113. external_stylesheets = [dbc.themes.SPACELAB, dbc.icons.BOOTSTRAP]
  114. app = dash.Dash(__name__, external_stylesheets = external_stylesheets)
  115. filter_box = html.Div(children=[
  116. html.Div(children=[
  117. html.Label(&#39;Day of the week:&#39;, style={&#39;paddingTop&#39;: &#39;2rem&#39;}),
  118. dcc.Dropdown(
  119. id=&#39;DATE&#39;,
  120. options=[
  121. {&#39;label&#39;: x, &#39;value&#39;: x} for x in df[&#39;DATE&#39;].unique()
  122. ],
  123. value=df[&#39;DATE&#39;].unique(),
  124. multi=True
  125. ),
  126. ], className=&quot;four columns&quot;,
  127. style={&#39;padding&#39;:&#39;2rem&#39;, &#39;margin&#39;:&#39;1rem&#39;} )
  128. ])
  129. app.layout = dbc.Container([
  130. dbc.Row([
  131. dbc.Col(html.Div(filter_box, className=&quot;bg-secondary h-100&quot;), width=2),
  132. dbc.Col([
  133. dbc.Row([
  134. dbc.Col(dcc.Graph(id = &#39;date-bar-chart&#39;),
  135. ),
  136. ]),
  137. ], width=5),
  138. ])
  139. ], fluid=True)
  140. @app.callback(
  141. Output(&#39;date-bar-chart&#39;, &#39;figure&#39;),
  142. [Input(&quot;DATE&quot;, &quot;value&quot;),
  143. ])
  144. def date_chart(date):
  145. if date:
  146. dff = df[df[&#39;DATE&#39;].isin(date)]
  147. count = dff.groupby([&#39;DATE&#39;,&quot;DOW&quot;])[&#39;DATE&#39;].count().reset_index(name=&#39;counts&#39;)
  148. data = px.bar(x = count[&#39;DATE&#39;],
  149. y = count[&#39;counts&#39;],
  150. color = count[&#39;DOW&#39;],
  151. color_discrete_map = cats,
  152. )
  153. layout = go.Layout(title = &#39;Date&#39;)
  154. fig = go.Figure(data = data, layout = layout)
  155. return fig
  156. else:
  157. raise PreventUpdate
  158. if __name__ == &#39;__main__&#39;:
  159. app.run_server(debug=False, port = 8051)
  160. I used groupby in `callback` to return new dataframe and then use it to make graph. Hope this help.
  161. [![enter image description here][1]][1]
  162. [1]: https://i.stack.imgur.com/fylgg.png
  163. </details>

huangapple
  • 本文由 发表于 2023年2月16日 14:00:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75468388.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定