1

I want to show all average temperatures of each month in a small chart for every year. My first issue is printing the legend for the colder (blue) and warmer (respectively red) temperatures and giving colour to the chart itself. My second issue is connected with looping through the data, ending in getting the following error: TypeError: unsupported operand type(s) for /: 'tuple' and 'int'. The amount of the years doesn't always have to be an even number. How can I nicely represent that in the loop?

How can I nake the chart like the picture underneath, including the coloured legend and chart.

What I want:

  • displaying all the years with all average temperatures of each month
  • coloured legend and chart
  • (It doesn't matter whether matloblib or seaborn)
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
d = {'year': [2001, 2001, 2001, 2001, 
              2002, 2002, 2002, 2002],
     'month': [1, 2,3,4,
              1,2,3,4],
     'temperature': [10,20,15,20,
                     20,10,5,10]}
df = pd.DataFrame(data=d)

df.head()


fig, axs = plt.subplots(int(len(df.year.unique()) / 2), int(len(df.year.unique()) / 2))

for i in enumerate(df.year.unique()):
    for j in range(int(i/2)):
        for k in range(int(i/2)):
            month = df['month'].unique()
            temperature = df[df['year'] == i].groupby('month')['temperature'].mean().values
            axs[j][k].bar(month, temperature)
plt.show()
    


TypeError: unsupported operand type(s) for /: 'tuple' and 'int'

enter image description here

Test
  • 571
  • 13
  • 32

1 Answers1

2

Seaborn with its facetgrid integrated plots gets you quite far. Plotting years in rows and columns like this is as simple as just using col="year", col_wrap=10.

In seaborn we prefer to use the facetgrid enabled plotting functions since they are flexible, like shown here in this example with catplot.

Here's an example, with some random data to fill out

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

years = np.arange(1990, 2022, 1).reshape((-1, 1))
months = np.array([5, 6, 7, 8]).reshape((1, 4))
years, months = (np.broadcast_arrays(years, months))

d = {'year': years.flatten(),
     'month': months.flatten(),
     'temperature': np.random.randint(0, 25, size=years.size),
    }
df = pd.DataFrame(data=d)



fg = sns.catplot(data=df, kind='bar', x='month', y='temperature', hue='temperature',
                 palette='Reds', col='year', col_wrap=10,
                 height=2, aspect=0.8, dodge=False, ci=None);
fg.set_titles(col_template="{col_name}");
fg.legend.remove()

# Hackily add a colorbar too
norm = plt.Normalize(df.temperature.min(), df.temperature.max())
sm = plt.cm.ScalarMappable(cmap="Reds", norm=norm)
sm.set_array([])

cax = fg.figure.add_axes([0.96, .12, .02, .8])
fg.figure.colorbar(sm, cax=cax);

The fg is the facetgrid that we can use to access indidivual axes and do further tweaks. All axes would be accessed by using a loop over fg.axes.

The absolute weak point here is that seaborn doesn't support continuous hue coloring by values (It's a future project as of this writing, see this issue). So we don't have great hue interpolation and no continuous color bar automatically.

However, I've added a colorbar workaround - all credit to this answer. It must be said that the hues and the colorbar are not exactly in sync.

enter image description here

creanion
  • 2,319
  • 2
  • 13
  • 17
  • Thank you very much, I really appreciate it!! Is there an option to determine the color plaette yourself? So that it goes from cold to warm (from blue to red) ? – Test Nov 03 '21 at 19:12
  • And I got `AttributeError: 'FacetGrid' object has no attribute 'figure'` :/ – Test Nov 03 '21 at 19:13
  • 1
    The attribute error is probably if you have a slightly older version. The old name is `fig` but now then deprecated in favour of `figure`. The palette name - `'Reds'`, appearing twice (sorry) determines the palette. Name or other colormap object should work. – creanion Nov 03 '21 at 19:14
  • Thank you very much!! :) Yes it was `fig`. Have to upgrade it. Thank you!! – Test Nov 03 '21 at 19:15