英文:
Initial plot not clearing when using dropdown menu to choose new data
问题
我正在自学如何使用ipywidgets包,通过对每个国家的总covid死亡人数进行分析,并希望创建一个带有下拉菜单的交互式图表来选择国家。
我的代码几乎完美运行。唯一的问题是,当我选择一个新的国家时,初始图表不会清除,我会留下两个图表,选择的正确图表和初始图表(如下图所示)。
请问有人能指导我如何去除初始图表吗?
以下是我正在使用的代码:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import ipywidgets as widgets
import seaborn as sns
# 获取数据集
data_url = "https://raw.githubusercontent.com/owid/covid-19-data/master/public/data/cases_deaths/total_deaths_per_million.csv"
df = pd.read_csv(data_url, index_col=0, parse_dates=[0], engine='python')
# 将缺失值填充为0
df.fillna(0, inplace=True)
df.head()
# 添加年周列
df['Year_Week'] = df.index.to_period('W').strftime('%Y-%U')
# 仅保留每周最后一天并更改为日期时间类型
df = df.groupby(df['Year_Week']).last('1D')
df.index = pd.to_datetime(df.index + '-0', format='%Y-%U-%w')
# 删除不是国家的列
df_country = df.drop(['World',
'Africa',
'Asia',
'Europe',
'European Union',
'High income',
'Low income',
'Lower middle income',
'North America',
'South America',
'Upper middle income'],
axis=1)
# 创建函数以根据所选国家更新图表
def update_plot(country):
ax.clear() # 清除现有图表
ax.plot(df.index, df_country[country]) # 绘制所选国家
# 设置x轴刻度位置和标签
xticks = pd.date_range(start=df_country.index[0].strftime('%Y-01-01'), end=df_country.index[-1], freq='AS')
xticklabels = [x.strftime('%Y') for x in xticks]
ax.set_xticks(xticks)
ax.set_xticklabels(xticklabels)
ax.set_title(f"每百万人的总死亡人数 ({country})") # 更新图表标题
ax.set_xlabel("日期")
ax.set_ylabel("每百万人的死亡人数")
fig.canvas.draw() # 重新绘制画布
# 创建包含国家名称作为选项的下拉菜单
country_dropdown = widgets.Dropdown(
options=df_country.columns,
value=df_country.columns[0],
description='国家'
)
# 创建图表
fig, ax = plt.subplots()
update_plot(country_dropdown.value) # 初始图表
# 设置小部件交互
output = widgets.Output()
display(country_dropdown, output)
def on_change(change):
if change['type'] == 'change' and change['name'] == 'value':
with output:
output.clear_output()
update_plot(change['new'])
display(fig)
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:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import ipywidgets as widgets
import seaborn as sns
# Get dataset
data_url = "https://raw.githubusercontent.com/owid/covid-19-data/master/public/data/cases_deaths/total_deaths_per_million.csv"
df = pd.read_csv(data_url, index_col=0, parse_dates=[0], engine='python')
# na values = 0
df.fillna(0, inplace=True)
df.head()
# add year-week column
df['Year_Week'] = df.index.to_period('W').strftime('%Y-%U')
# keep only last day of week and change to datetime type
df = df.groupby(df['Year_Week']).last('1D')
df.index = pd.to_datetime(df.index + '-0', format='%Y-%U-%w')
# drop columns that aren't a country
df_country = df.drop(['World',
'Africa',
'Asia',
'Europe',
'European Union',
'High income',
'Low income',
'Lower middle income',
'North America',
'South America',
'Upper middle income'],
axis=1)
# create function to update plot based on selected country
def update_plot(country):
ax.clear() # clear existing plot
ax.plot(df.index, df_country[country]) # plot selected country
# set x-axis tick locations and labels
xticks = pd.date_range(start=df_country.index[0].strftime('%Y-01-01'), end=df_country.index[-1], freq='AS')
xticklabels = [x.strftime('%Y') for x in xticks]
ax.set_xticks(xticks)
ax.set_xticklabels(xticklabels)
ax.set_title(f"Total deaths per million ({country})") # update plot title
ax.set_xlabel("Date")
ax.set_ylabel("Deaths per million")
fig.canvas.draw() # redraw canvas
# create drop-down menu with country names as options
country_dropdown = widgets.Dropdown(
options=df_country.columns,
value=df_country.columns[0],
description='Country'
)
# create plot
fig, ax = plt.subplots()
update_plot(country_dropdown.value) # initial plot
# set up widget interaction
output = widgets.Output()
display(country_dropdown, output)
def on_change(change):
if change['type'] == 'change' and change['name'] == 'value':
with output:
output.clear_output()
update_plot(change['new'])
display(fig)
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.
%matplotlib widget
# [...]
# create plot
fig, ax = plt.subplots()
update_plot(country_dropdown.value) # initial plot
# set up widget interaction
display(country_dropdown)
def on_change(change):
if change['type'] == 'change' and change['name'] == 'value':
update_plot(change['new'])
plt.draw()
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.
%matplotlib widget
# [...]
# create plot
fig, ax = plt.subplots()
update_plot(country_dropdown.value) # initial plot
# set up widget interaction
display(country_dropdown)
def on_change(change):
if change['type'] == 'change' and change['name'] == 'value':
update_plot(change['new'])
plt.draw()
country_dropdown.observe(on_change)
Execute the cell
Change the dropdown value. The figure is updated in the cell output without the initial one
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论