英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。




评论