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

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

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

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

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:

确定