'AttributeError: 'NoneType' object has no attribute 'dpi_scale_trans'
Having checked through StackOverflow for a possible solution to the above error that I encountered, I found some solutions which were not able to solve this particular issue. The following image shows the error encountered and the undesirable figure obtained while trying to plot multiple axes on a figure:
This is an image of the expected output: 
Also, the data I am working with can be found at: https://drive.google.com/file/d/1ZxD3BwpJfEVMWPoxu-aom_wXawMfSywk/view?usp=sharing
Below is the set of codes that I have scripted, and I seem to have hit a roadblock. I would appreciate any help that will guide me to achieve the expected output @image2.
import matplotlib.dates as md
# Date already in DateTime index
dk1 = data.loc["1991":"2000"] # selects all rows from 1991 - 2000
dk2 = data.loc["2001":"2010"] # selects all rows from 2001 - 2010
dk3 = data.loc["2011":"2020"] # selects all rows from 2011 - 2020
plt.rcParams['font.size'] = 18
fig = plt.figure(figsize=(20,15)) # Create a figure for the plot
# Add three axes to the plots
ax1 = plt.subplot(111)
ax2 = plt.subplot(212)
ax3 = plt.subplot(313)
# Plot the data
ax1.plot(dk1.TX, label = 'Max temp')
ax2.plot(dk2.TX, label = 'Max temp')
ax3.plot(dk3.TX, label = 'Max temp')
# Set the title
ax1.set_title("Station: Ikeja, 1991~2000, tmax\n")
ax2.set_title("Station: Ikeja, 2001~2010, tmax\n")
ax3.set_title("Station: Ikeja, 2011~2020, tmax\n")
ax1.legend() # Plot the legend for first axes
ax2.legend() # Plot the legend for second axes
ax3.legend() # Plot the legend for third axes
# Set the x- and y-axis label
ax1.set_ylabel('Temperature (°C)\n') # Set the Y-Axis label
ax1.set_xlabel('\nYear') # Set the X-Axis label
ax2.set_ylabel('Temperature (°C)\n') # Set the Y-Axis label
ax2.set_xlabel('\nYear') # Set the X-Axis label
ax3.set_ylabel('Temperature (°C)\n') # Set the Y-Axis label
ax3.set_xlabel('\nYear') # Set the X-Axis label
# formatted X axis in Year
ax1.xaxis.set_major_locator(md.YearLocator(month = 1, day = 1)) # formatted X axis in Year
ax1.xaxis.set_major_formatter(md.DateFormatter('%Y')) # set the date format to the year shortname
ax2.xaxis.set_major_locator(md.YearLocator(month = 1, day = 1)) # formatted X axis in Year
ax2.xaxis.set_major_formatter(md.DateFormatter('%Y')) # set the date format to the year shortname
ax3.xaxis.set_major_locator(md.YearLocator(month = 1, day = 1)) # formatted X axis in Year
ax3.xaxis.set_major_formatter(md.DateFormatter('%Y')) # set the date format to the year shortname
# Set the limits (range) of the X-Axis
ax1.set_xlim([pd.to_datetime('1991 1 1', format = format),
pd.to_datetime('2000 12 31', format = format)])
ax2.set_xlim([pd.to_datetime('2001 1 1', format = format),
pd.to_datetime('2010 12 31', format = format)])
ax3.set_xlim([pd.to_datetime('2010 1 1', format = format),
pd.to_datetime('2020 12 31', format = format)])
plt.show()
Thanks.
Solution 1:[1]
The error is due to the argument passed to matplotlib.pyplot.subplot: since you want three plot on three different rows (same column), then you should use:
ax1 = plt.subplot(3, 1, 1)
ax2 = plt.subplot(3, 1, 2)
ax3 = plt.subplot(3, 1, 3)
In any case, your code need some changes in order to achieve the results you want.
First of all it is wise to convert 'Time' column from str type to datetime:
data['time'] = pd.to_datetime(data['time'], format = '%m/%d/%Y')
Then, since you need to filter data based on year, you should create a column with the year:
data['year'] = data['time'].dt.year
At this point you can filter your data based on the 'year' column:
dk1 = data[(data['year'] >= 1991) & (data['year'] <= 2000)] # selects all rows from 1991 - 2000
dk2 = data[(data['year'] >= 2001) & (data['year'] <= 2010)] # selects all rows from 2001 - 2010
dk3 = data[(data['year'] >= 2011) & (data['year'] <= 2020)] # selects all rows from 2011 - 2020
As already mentioned, you should create the subplots in the proper way:
ax1 = plt.subplot(3, 1, 1)
ax2 = plt.subplot(3, 1, 2)
ax3 = plt.subplot(3, 1, 3)
Finally, pay attention to the set_xlim code: format is a special keyword in python:
ax1.set_xlim([pd.to_datetime('1991 1 1', format = '%Y %m %d'),
pd.to_datetime('2000 12 31', format = '%Y %m %d')])
ax2.set_xlim([pd.to_datetime('2001 1 1', format = '%Y %m %d'),
pd.to_datetime('2010 12 31', format = '%Y %m %d')])
ax3.set_xlim([pd.to_datetime('2010 1 1', format = '%Y %m %d'),
pd.to_datetime('2020 12 31', format = '%Y %m %d')])
Complete code
import matplotlib.dates as md
import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_csv(r'data/max_temp.csv')
data['time'] = pd.to_datetime(data['time'], format = '%m/%d/%Y')
data['year'] = data['time'].dt.year
# # Date already in DateTime index
dk1 = data[(data['year'] >= 1991) & (data['year'] <= 2000)] # selects all rows from 1991 - 2000
dk2 = data[(data['year'] >= 2001) & (data['year'] <= 2010)] # selects all rows from 2001 - 2010
dk3 = data[(data['year'] >= 2011) & (data['year'] <= 2020)] # selects all rows from 2011 - 2020
plt.rcParams['font.size'] = 18
fig = plt.figure(figsize=(20,15)) # Create a figure for the plot
# Add three axes to the plots
ax1 = plt.subplot(3, 1, 1)
ax2 = plt.subplot(3, 1, 2)
ax3 = plt.subplot(3, 1, 3)
# Plot the data
ax1.plot(dk1.time, dk1.TX, label = 'Max temp')
ax2.plot(dk2.time, dk2.TX, label = 'Max temp')
ax3.plot(dk3.time, dk3.TX, label = 'Max temp')
# Set the title
ax1.set_title("Station: Ikeja, 1991~2000, tmax\n")
ax2.set_title("Station: Ikeja, 2001~2010, tmax\n")
ax3.set_title("Station: Ikeja, 2011~2020, tmax\n")
ax1.legend() # Plot the legend for first axes
ax2.legend() # Plot the legend for second axes
ax3.legend() # Plot the legend for third axes
# Set the x- and y-axis label
ax1.set_ylabel('Temperature (°C)\n') # Set the Y-Axis label
ax1.set_xlabel('\nYear') # Set the X-Axis label
ax2.set_ylabel('Temperature (°C)\n') # Set the Y-Axis label
ax2.set_xlabel('\nYear') # Set the X-Axis label
ax3.set_ylabel('Temperature (°C)\n') # Set the Y-Axis label
ax3.set_xlabel('\nYear') # Set the X-Axis label
# formatted X axis in Year
ax1.xaxis.set_major_locator(md.YearLocator(month = 1, day = 1)) # formatted X axis in Year
ax1.xaxis.set_major_formatter(md.DateFormatter('%Y')) # set the date format to the year shortname
ax2.xaxis.set_major_locator(md.YearLocator(month = 1, day = 1)) # formatted X axis in Year
ax2.xaxis.set_major_formatter(md.DateFormatter('%Y')) # set the date format to the year shortname
ax3.xaxis.set_major_locator(md.YearLocator(month = 1, day = 1)) # formatted X axis in Year
ax3.xaxis.set_major_formatter(md.DateFormatter('%Y')) # set the date format to the year shortname
# Set the limits (range) of the X-Axis
ax1.set_xlim([pd.to_datetime('1991 1 1', format = '%Y %m %d'),
pd.to_datetime('2000 12 31', format = '%Y %m %d')])
ax2.set_xlim([pd.to_datetime('2001 1 1', format = '%Y %m %d'),
pd.to_datetime('2010 12 31', format = '%Y %m %d')])
ax3.set_xlim([pd.to_datetime('2010 1 1', format = '%Y %m %d'),
pd.to_datetime('2020 12 31', format = '%Y %m %d')])
plt.show()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |


