IMF的官方网站可以查到世界大部分国家的经济数据,比如增长率,GDP,人均GDP,人口等等。
我用tkinter实现了从IMF获取数据,并实现页面展示,非常便利。这大概是经济爱好者的强迫症吧。
首先从这里获取Excel: https://www.imf.org/external/datamapper/datasets/WEO
然后对Excel进行一点加工,如图
然后运行python程序:
#-*- coding:utf-8 -*-
import requests,time,datetime
import tkinter as tk #使用Tkinter前需要先导入
from tkinter import filedialog,messagebox,ttk
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sqlalchemy import create_engine
plt.rcParams['font.sans-serif']=['SimHei']
conn=create_engine("mysql+pymysql://root:dio350922@127.0.0.1:3306/economy")
window = tk.Tk()
dfc=pd.read_sql("select country,country_cn 国家 from countrylist where iscountry='Y' order by pinyin",conn) #国家中英文列表
countrymap=dict(zip(dfc['country'],dfc['国家'])) #国家英中文对照
countrylist=dfc['国家'].tolist() #国家列表
indexmap={'增长率':'growth','GDP':'gdp','人均GDP':'rjgdp','GDP(PPP)':'ppp','人均GDP(PPP)':'rjppp','人口':'renkou'}
indexlist=list(indexmap)
typemap={'线形图':'line','柱状图':'bar'}
window.title('经济指标曲线图')
w_width=1100
w_height=750
scn_width=window.maxsize()[0]
x_point=(scn_width-w_width)//2
window.geometry('%dx%d+%d+%d' %(w_width,w_height,x_point,100))
window.wm_attributes('-topmost',True)
window.tk_focusFollowsMouse()
window.bind("<Escape>",lambda event:window.iconify())
#更新数据
def getfile(type):
file=filedialog.askopenfilename(filetype=[('Excel','.xls'),('Excel','.xlsx')])
df=pd.read_excel(file)
index=df.columns[0]
df.dropna(thresh=1,inplace=True) #去空行
df[index]=df[index].apply(lambda x:countrymap[x.strip()] if x.strip() in countrymap else x) #国家翻译为中文
df.set_index(index,inplace=True) #国家列为索引
df.dropna(thresh=1,inplace=True) #去最后一行
df.index.name='国家' #修改索引列的名称为国家
for i in df.columns:
df[i].mask(df[i]=='no data',np.nan,inplace=True) #处理no data
df=df.astype(float).reset_index() #数据转为float
df.to_sql(name=type,con=conn, if_exists='replace', index=False) #导入mysql
messagebox.showinfo('提示',type+"数据更新完成")
#读取数据出图
def getdata():
index=var.get() #经济指标
kind=type.get() #图表类型
table=indexmap[index] #指标对应的表名
chosed=[i.get() for i in v if i.get()] #选择的国家
startyear=start_year.get()
if(not startyear):
messagebox.showerror('警告','没有起始年份')
return False
endyear=end_year.get()
if(not endyear):
messagebox.showerror('警告','没有结束年份')
return False
endyear=str(int(endyear)+1)
dfa=[]
for country in chosed:
sql="select * from {} where 国家='{}'".format(table,country)
try:
dfx=pd.read_sql(sql,conn)
except Exception as e:
messagebox.showerror('警告',str(e))
dfx=dfx.set_index('国家').T
dfx.columns.name=''
dfx.index.name='年份'
dfa.append(dfx)
dff=pd.concat(dfa,axis=1) #聚合结果
datelist=pd.date_range(start=startyear,end=endyear,freq='Y').strftime('%Y') #日期范围
dff=dff.loc[datelist]
dff.plot(kind=typemap[kind],title=index+' ') #出图
plt.show()
#反选
def unselectall():
for index,item in enumerate(countrylist):
v[index].set('')
#全选
def selectall():
for index,item in enumerate(countrylist):
v[index].set(item)
frame0=tk.Frame(window,pady=10,padx=15)
frame0.grid(row=0,column=0,sticky='w')
ttk.Button(frame0,text="载入增长率",command=lambda:getfile('growth')).grid(row=0,column=0)
ttk.Button(frame0,text="载入GDP",command=lambda:getfile('gdp')).grid(row=0,column=1)
ttk.Button(frame0,text="载入人均GDP",command=lambda:getfile('rjgdp')).grid(row=0,column=2)
ttk.Button(frame0,text="载入GDP(PPP)",command=lambda:getfile('ppp')).grid(row=0,column=3)
ttk.Button(frame0,text="载入人均GDP(PPP)",command=lambda:getfile('rjppp')).grid(row=0,column=4)
ttk.Button(frame0,text="载入人口",command=lambda:getfile('renkou')).grid(row=0,column=5)
#全选反选
frame1=tk.Frame(window,pady=6,padx=15)
frame1.grid(row=1,column=0)
opt=tk.IntVar()
ttk.Radiobutton(frame1,text='全选',variable=opt,value=1,command=selectall).grid(row=0,column=0,sticky='w')
ttk.Radiobutton(frame1,text='反选',variable=opt,value=0,command=unselectall).grid(row=0,column=1,sticky='w')
v=[]
for index,item in enumerate(countrylist):
v.append(tk.StringVar())
ttk.Checkbutton(frame1,text=item,variable=v[-1],onvalue=item,offvalue="").grid(row=index//10+1,column=index%10,sticky='w')
frame2=tk.Frame(window,padx=15,pady=15)
frame2.grid(row=2,column=0,sticky='w')
var=tk.StringVar()
type=tk.StringVar()
ttk.Label(frame2,text="请选择指标:").grid(row=0,column=0,sticky='w')
chosen=ttk.Combobox(frame2,textvariable=var)
chosen.grid(row=0,column=1,sticky='w')
chosen['values']=indexlist
chosen.current(0)
ttk.Label(frame2,text="请选择图表类型:").grid(row=1,column=0,sticky='w')
chosen=ttk.Combobox(frame2,textvariable=type)
chosen.grid(row=1,column=1,sticky='w')
chosen['values']=['线形图','柱状图']
chosen.current(0) #默认是第一个
start_year=tk.StringVar()
end_year=tk.StringVar()
start_year.set('1980')
nowyear=datetime.datetime.now().strftime('%Y')
end_year.set(nowyear)
ttk.Label(frame2,text="起始年份").grid(row=2,column=0,sticky='w',pady=6)
ttk.Spinbox(frame2,textvariable=start_year,from_=1980,to=nowyear,increment=1).grid(row=2,column=1,sticky='w')
ttk.Label(frame2,text="结束年份").grid(row=2,column=2,sticky='w')
ttk.Spinbox(frame2,textvariable=end_year,from_=1980,to=nowyear,increment=1).grid(row=2,column=3)
ttk.Button(frame2,text="点击获取曲线图",command=getdata).grid(row=3,column=0)
window.mainloop()
效果如图:
看看这么多国家,你认识几个