Я стремлюсь построить два кадра данных на одном графике - один кадр минимальных месячных температур, другой кадр максимальных месячных температур в среднем за каждое десятилетие с 1930 года для города Канберра. Я хочу, чтобы два кадра данных имели общую легенду. Чтобы добавить в задачу, я хочу, чтобы легенда имела два столбца.
Я могу получить общую легенду, но только в одном столбце. Или я могу повторить легенду в двух столбцах. Я не освоил одну общую легенду в двух столбцах. См. Следующее изображение.
![chart of minimum and maximum temperatures in Canberra since 1930 by decade](https://i.stack.imgur.com/RX233.png)
Ниже приведен полный код, включая данные из Интернета, но моя проблема в последних нескольких строках кода.
# Look at temperature data for Canberra
# --- initialise
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import requests
import io
# --- some graphics management
plt.style.use('./bryan.mplstyle')
LOCATION = './Charts/Canb-'
def plot_save_and_close(ax, title, xlabel, ylabel,
filename, legend=True, bar_labels=0):
"""Add the usual chart annotations,
save to file and close the plot """
ax.set_title(title)
ax.set_xlabel(xlabel)
ax.set_ylabel(ylabel)
fig = ax.figure
fig.tight_layout(pad=1)
if legend and not ax.get_legend():
l = ax.legend(loc='best', fontsize='small')
if bar_labels:
for i, t in enumerate(ax.get_xticklabels()):
if ((i-3) % bar_labels) != 0:
t.set_visible(False)
fig.savefig(filename, dpi=125)
plt.close()
# --- Get the data
# Data from Australian Bureau pf Meteorology
url_stem = 'http://www.bom.gov.au/climate/change/hqsites/data/temp/'
canberra = '070351'
url_min = url_stem+'tmin.'+canberra+'.daily.csv'
url_max = url_stem+'tmax.'+canberra+'.daily.csv'
# download minimum temperatures
min_df = pd.read_csv(io.StringIO(requests.get(
url_min).content.decode('utf-8')),
header=0, index_col=0, parse_dates=[0])
min_df = min_df.drop(min_df.index[0])[[min_df.columns[0]]]
min_df.columns = ['Minimum']
# download maximum temperatures
max_df = pd.read_csv(io.StringIO(requests.get(
url_max).content.decode('utf-8')),
header=0, index_col=0, parse_dates=[0])
max_df = max_df.drop(max_df.index[0])[[max_df.columns[0]]]
max_df.columns = ['Maximum']
# combine into a single dataframe
df = min_df.join(max_df, how='outer')
# let's augment with the latest daily data - TO DO
# provide some grouping tags for the data
df['calendar year'] = df.index.to_period(freq='A-DEC')
df['winter year'] = df.index.to_period(freq='A-MAY')
df['decade begining'] = (df.index.year // 10) * 10
df['tri-decade beginning'] = (((df.index.year - 1900) // 30) * 30) + 1900
df['julian day'] = df.index.dayofyear
df['Month'] = df.index.month
# check for missing data by year
#print('Missing max data by calandar year: ')
#print(df[df['Maximum'].isna()].groupby('calendar year')['Maximum'].size())
#print('Missing min data by calandar year: ')
#print(df[df['Minimum'].isna()].groupby('calendar year')['Minimum'].size())
# note: substantial missing data for Canberra between 1920-25 inclusive
df = df[df.index >= pd.Timestamp('1926-01-01')].copy() # not a slice
df_saved = df.copy() # keep a copy of the original to return to
# let's plot decadal monthly averages - both maximum and minimums
df = df_saved.copy()
df = df.groupby('decade begining').filter(lambda x: len(x) >= 3300) # close to full decades
df = df.groupby(['decade begining', 'Month'])['Maximum', 'Minimum'].mean().unstack(level=0)
max = df['Maximum']
min = df['Minimum']
colors = plt.cm.coolwarm(np.linspace(0,1,len(max.columns)))
ax = max.plot(color=colors, legend=True)
legend = ax.legend(title='Decade begining', ncol=2, loc='best',fontsize='small')
ax = min.plot(ax=ax, color=colors, legend=False)
plot_save_and_close(ax, 'Canberra: Average Monthly Min and Max Temp by Decade',
'Month', 'Degrees Celsius', LOCATION+'unsmoothed-decadal-average-monthly.png')