初始图表在使用下拉菜单选择新数据时未清除。

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

Initial plot not clearing when using dropdown menu to choose new data

问题

我正在自学如何使用ipywidgets包,通过对每个国家的总covid死亡人数进行分析,并希望创建一个带有下拉菜单的交互式图表来选择国家。

我的代码几乎完美运行。唯一的问题是,当我选择一个新的国家时,初始图表不会清除,我会留下两个图表,选择的正确图表和初始图表(如下图所示)。

初始图表在使用下拉菜单选择新数据时未清除。

请问有人能指导我如何去除初始图表吗?

以下是我正在使用的代码:

  1. import numpy as np
  2. import pandas as pd
  3. import matplotlib.pyplot as plt
  4. import ipywidgets as widgets
  5. import seaborn as sns
  6. # 获取数据集
  7. data_url = "https://raw.githubusercontent.com/owid/covid-19-data/master/public/data/cases_deaths/total_deaths_per_million.csv"
  8. df = pd.read_csv(data_url, index_col=0, parse_dates=[0], engine='python')
  9. # 将缺失值填充为0
  10. df.fillna(0, inplace=True)
  11. df.head()
  12. # 添加年周列
  13. df['Year_Week'] = df.index.to_period('W').strftime('%Y-%U')
  14. # 仅保留每周最后一天并更改为日期时间类型
  15. df = df.groupby(df['Year_Week']).last('1D')
  16. df.index = pd.to_datetime(df.index + '-0', format='%Y-%U-%w')
  17. # 删除不是国家的列
  18. df_country = df.drop(['World',
  19. 'Africa',
  20. 'Asia',
  21. 'Europe',
  22. 'European Union',
  23. 'High income',
  24. 'Low income',
  25. 'Lower middle income',
  26. 'North America',
  27. 'South America',
  28. 'Upper middle income'],
  29. axis=1)
  30. # 创建函数以根据所选国家更新图表
  31. def update_plot(country):
  32. ax.clear() # 清除现有图表
  33. ax.plot(df.index, df_country[country]) # 绘制所选国家
  34. # 设置x轴刻度位置和标签
  35. xticks = pd.date_range(start=df_country.index[0].strftime('%Y-01-01'), end=df_country.index[-1], freq='AS')
  36. xticklabels = [x.strftime('%Y') for x in xticks]
  37. ax.set_xticks(xticks)
  38. ax.set_xticklabels(xticklabels)
  39. ax.set_title(f"每百万人的总死亡人数 ({country})") # 更新图表标题
  40. ax.set_xlabel("日期")
  41. ax.set_ylabel("每百万人的死亡人数")
  42. fig.canvas.draw() # 重新绘制画布
  43. # 创建包含国家名称作为选项的下拉菜单
  44. country_dropdown = widgets.Dropdown(
  45. options=df_country.columns,
  46. value=df_country.columns[0],
  47. description='国家'
  48. )
  49. # 创建图表
  50. fig, ax = plt.subplots()
  51. update_plot(country_dropdown.value) # 初始图表
  52. # 设置小部件交互
  53. output = widgets.Output()
  54. display(country_dropdown, output)
  55. def on_change(change):
  56. if change['type'] == 'change' and change['name'] == 'value':
  57. with output:
  58. output.clear_output()
  59. update_plot(change['new'])
  60. display(fig)
  61. country_dropdown.observe(on_change)
英文:

I am teaching myself how to use the ipywidgets package by doing analysis on the total covid deaths for each country and want to make an interactive plot with a dropdown menu for Country choice.

My code works almost perfectly. The only thing is that when I chose a new country, the initial plot does not clear and I am left with 2 plots, the correct plot from choice, and the initial plot (as seen in the image below).

初始图表在使用下拉菜单选择新数据时未清除。

Can someone please point me in the right direction as to how I can remove the initial plot?

Here is the code that I am using:

  1. import numpy as np
  2. import pandas as pd
  3. import matplotlib.pyplot as plt
  4. import ipywidgets as widgets
  5. import seaborn as sns
  6. # Get dataset
  7. data_url = "https://raw.githubusercontent.com/owid/covid-19-data/master/public/data/cases_deaths/total_deaths_per_million.csv"
  8. df = pd.read_csv(data_url, index_col=0, parse_dates=[0], engine='python')
  9. # na values = 0
  10. df.fillna(0, inplace=True)
  11. df.head()
  12. # add year-week column
  13. df['Year_Week'] = df.index.to_period('W').strftime('%Y-%U')
  14. # keep only last day of week and change to datetime type
  15. df = df.groupby(df['Year_Week']).last('1D')
  16. df.index = pd.to_datetime(df.index + '-0', format='%Y-%U-%w')
  17. # drop columns that aren't a country
  18. df_country = df.drop(['World',
  19. 'Africa',
  20. 'Asia',
  21. 'Europe',
  22. 'European Union',
  23. 'High income',
  24. 'Low income',
  25. 'Lower middle income',
  26. 'North America',
  27. 'South America',
  28. 'Upper middle income'],
  29. axis=1)
  30. # create function to update plot based on selected country
  31. def update_plot(country):
  32. ax.clear() # clear existing plot
  33. ax.plot(df.index, df_country[country]) # plot selected country
  34. # set x-axis tick locations and labels
  35. xticks = pd.date_range(start=df_country.index[0].strftime('%Y-01-01'), end=df_country.index[-1], freq='AS')
  36. xticklabels = [x.strftime('%Y') for x in xticks]
  37. ax.set_xticks(xticks)
  38. ax.set_xticklabels(xticklabels)
  39. ax.set_title(f"Total deaths per million ({country})") # update plot title
  40. ax.set_xlabel("Date")
  41. ax.set_ylabel("Deaths per million")
  42. fig.canvas.draw() # redraw canvas
  43. # create drop-down menu with country names as options
  44. country_dropdown = widgets.Dropdown(
  45. options=df_country.columns,
  46. value=df_country.columns[0],
  47. description='Country'
  48. )
  49. # create plot
  50. fig, ax = plt.subplots()
  51. update_plot(country_dropdown.value) # initial plot
  52. # set up widget interaction
  53. output = widgets.Output()
  54. display(country_dropdown, output)
  55. def on_change(change):
  56. if change['type'] == 'change' and change['name'] == 'value':
  57. with output:
  58. output.clear_output()
  59. update_plot(change['new'])
  60. display(fig)
  61. country_dropdown.observe(on_change)

答案1

得分: 1

If you're working in a notebook, make your plot interactive by adding %matplotlib widget at the beginning of the cell.

Then, you don't need to use Output, simply update your fig and re-draw it in the event callback function.

  1. %matplotlib widget
  2. # [...]
  3. # create plot
  4. fig, ax = plt.subplots()
  5. update_plot(country_dropdown.value) # initial plot
  6. # set up widget interaction
  7. display(country_dropdown)
  8. def on_change(change):
  9. if change['type'] == 'change' and change['name'] == 'value':
  10. update_plot(change['new'])
  11. plt.draw()
  12. country_dropdown.observe(on_change)

Execute the cell

初始图表在使用下拉菜单选择新数据时未清除。

Change the dropdown value. The figure is updated in the cell output without the initial one

初始图表在使用下拉菜单选择新数据时未清除。

英文:

If you're working in a notebook, make your plot interactive by adding %matplotlib widget at the beginning of the cell.

Then, you don't need to use Output, simply update your fig and re-draw it in the event callback function.

  1. %matplotlib widget
  2. # [...]
  3. # create plot
  4. fig, ax = plt.subplots()
  5. update_plot(country_dropdown.value) # initial plot
  6. # set up widget interaction
  7. display(country_dropdown)
  8. def on_change(change):
  9. if change['type'] == 'change' and change['name'] == 'value':
  10. update_plot(change['new'])
  11. plt.draw()
  12. country_dropdown.observe(on_change)

Execute the cell

初始图表在使用下拉菜单选择新数据时未清除。

Change the dropdown value. The figure is updated in the cell output without the initial one

初始图表在使用下拉菜单选择新数据时未清除。

huangapple
  • 本文由 发表于 2023年3月3日 19:48:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/75626715.html
匿名

发表评论

匿名网友

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

确定