我有一个来自世界卫生组织的数据框,使用的是JSON,如此
import requests
import pandas as pd
import json
from pandas import read_html
from pandas.io.json import json_normalize
import urllib2, json
import html5lib
#Measles - Number of deaths of children < 5 by country & year
url = "http://apps.who.int/gho/athena/data/GHO/MORT_100.json?profile=simple&filter=COUNTRY:*;CHILDCAUSE:CH6"
response2 = urllib2.urlopen(url)
response_json2 = json.loads(response2.read())
dfWHO2 = json_normalize(response_json2['fact'])
dfWHO2 = dfWHO2.loc[dfWHO2['dim.AGEGROUP']== '0-4 years']
WHOMeaslesChildhoodDeaths = dfWHO2.pivot('dim.COUNTRY','dim.YEAR','Value').astype(float)
#Measles First Dose Vaccination rate
url = "http://apps.who.int/gho/athena/data/GHO/WHS8_110.json?profile=simple&filter=COUNTRY:*"
response = urllib2.urlopen(url)
response_json = json.loads(response.read())
dfWHO1 = json_normalize(response_json['fact']).pivot('dim.COUNTRY','dim.YEAR','Value').astype(float)
WHOMeasles1stVaccRate = dfWHO1
WHOMeasles1stVaccRate = WHOMeasles1stVaccRate.loc[:,'2000':'2016']
#Combine Dataframes
WHOCombinedData = pd.concat([WHOMeasles1stVaccRate,WHOMeaslesChildhoodDeaths],axis=1,keys=['Rate','Deaths']).swaplevel(1,0,axis=1).sort_index(1)
#Transpose dataframes to get ready for Plotting
WHOData = WHOCombinedData.transpose()
dim.COUNTRY Afghanistan Albania Algeria Andorra Angola
dim.YEAR
2000 Deaths 10580 2 1550 0 1536
Rate 27 95 80 97 36
2001 Deaths 14120 0 1616 0 4643
Rate 37 95 83 97 65
2002 Deaths 6891 0 1646 0 6061
Rate 35 96 81 98 66
2003 Deaths 225 0 2567 0 2238
Rate 39 93 84 96 52
2004 Deaths 367 0 38 0 36
Rate 48 96 81 98 52
2005 Deaths 2042 0 32 0 432
Rate 50 97 83 94 32
我想用2行绘制每个图中的每个列,一个用于死亡,一个用于速率。
因为比例是如此不同,我需要在辅助Y轴上绘制其中一个
第一个问题是我无法在第二个Y轴上获得RATE。
接下来的问题是我想一次绘制多个图表 - 每个列都有一个,但我不知道如何做到这一点。我确实试图一次绘制一个,而不是最好的方法,但它几乎可以工作,但是有近200个国家,所以做一个更聪明的方法是非常必要的。
这是我为单个图表尝试的内容:
ax = WHOData.loc[:,'Afghanistan':'Afghanistan'].unstack().plot(secondary_y='True' ,kind='line', stacked=True)
ax2 = ax.twinx()
plt.show()
这就是我得到的结果:
我将非常感谢任何帮助
答案 0 :(得分:1)
您可以迭代列,绘图并显示如下:
from matplotlib import pyplot as plt
for country in df.columns: # Iterate over countries
df[[country]].unstack().plot(); # Unstack deaths and rates, plot
plt.show(); # Switch to new plot
请注意使用pyplot.show
。
修改强>
要单独绘制死亡率和费率,您可以使用subplot
:
for country in df.columns: # Iterate over countries
country_df = df[[country]].unstack().plot(); # Unstack deaths and rates
subplot(2, 1, 1);
plot(country_df[['Deaths']]);
subplot(2, 1, 2)
plot(country_df[['Rates']]);
plt.show(); # Switch to new plot
答案 1 :(得分:1)
Ami的第一段代码回答了我的问题的第二部分,如何让每个国家在一个单独的地块上展示。不幸的是,他的第二段代码没有成功地给出如何在辅助y轴上绘制第二个系列。
在这里进行一些研究: Matplotlib - Plots with different scales
我终于弄清楚了。我要做的第一件事就是分开Deaths&amp;有效率。这是必需的,因为Dataframe是一个具有Rate&amp; amp;的多变量。每年死亡 - 每个国家多年
之后我需要让matplotlib与死亡分开提供YAXIS费率,因为在许多情况下规模差别很大
当然可以有更简洁的方式来编写代码,但这里有一组有效的代码:
for country in WHOData.columns: # Iterate over countries
country_df = WHOData[[country]].unstack(); # Unstack deaths and rates
deaths = country_df.iloc[:, country_df.columns.get_level_values(1)=='Deaths']
rate = country_df.iloc[:, country_df.columns.get_level_values(1)=='Rate']
fig, ax1 = plt.subplots()
color = 'red'
ax1.set_xlabel('Years')
ax1.set_ylabel('Childhood (<4) Deaths by Measles', color=color)
ax1.plot(deaths, color=color)
ax1.tick_params(axis='y', labelcolor=color)
ax2 = ax1.twinx() # instantiate a second axes that shares the same x-axis
color = 'blue'
ax2.set_ylabel('Vaccination Rate 1st Dose', color=color) # we already handled the x-label with ax1
ax2.plot(rate, color=color)
ax2.tick_params(axis='y', labelcolor=color)
fig.tight_layout() # otherwise the right y-label is slightly clipped
plt.title(country)
plt.show()
这就是它产生的: