I have a raspberry pi running some hardware, and continuously generating data. Each day, I collect the data in a pandas dataframe, and it shoots off a summary email. That email needs to contain a pretty chart showing the data over time. Testing on my main machine (latest MacOS) works beautifully. The pi, however, outputs blank charts. Axes, labels, colors, and everything but the plots themselves. Just an empty chart. Both machines are running matplotlib 3.5.1. Please help me figure out why the plots are not rendering on the one machine, but just fine on the other.
#!/usr/bin/env python
import dill
import pandas
import datetime
from datetime import timedelta
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import subprocess
class Report():
def __init__(self, datafile):
# Saved dataframes
self.file = datafile
def runReport(self):
# Open data
saveIn = open(self.file, 'rb')
data = dill.load(saveIn)
# Close file
saveIn.close()
# Alias dataframe
systemData = data['systemReadings']
# Declare chart, set output size
fig = plt.figure(figsize = (14, 8.75))
## Plot1
# Create plot1 plot sharing an X-axis with Plot5
plot1 = fig.add_subplot()
# Display y-axis labels alongside Plot5
plot1.yaxis.tick_left()
# Display tick labels to left of tick line
rspine = plot1.spines['left']
# Display y-axis label to the left of the chart
plot1.yaxis.set_label_position("left")
# Y-axis range
plt.ylim((7.0, 8.5))
# Divide y-axis into 10 ticks
plt.locator_params(axis = 'y', nbins = 10)
# Limit x-axis to 00:00 - 23:59 range
plot1.set_xlim([datetime.date(2022,3,6), datetime.date(2022,3,7)])
# Link data and color line
plot1.plot(systemData['Plot1'], color = 'k', label = 'Plot1')
# Shares scale and label with Plot5
## Plot2
# Create Plot2 plot on X-axis with plot1
plot2 = plot1.twinx()
# Display y-axis labels to the right of scale line
rspine = plot2.spines['right']
# Adjust location of axis/labels so they're not on top of the other dataset sharing that side of the chart
rspine.set_position(('axes', 1.05))
# Y-axis range
plt.ylim((-0.05, 1))
# Divide y-axis into 10 tickmarks
plt.locator_params(axis = 'y', nbins = 10)
# Link data and line color
plot2.plot(systemData['Plot2'], color = 'orange', label = 'Plot2')
# Label and label color
plot2.set_ylabel('Plot2', color = 'orange')
## Plo3
# Create Estimated Plot3 plot on same X-axis with plot1
plot3 = plot1.twinx()
# Display ticks on left side of chart
plot3.yaxis.tick_left()
# Display tick labels to left of tick line
rspine = plot3.spines['left']
# Display y-axis label to the left of the chart
plot3.yaxis.set_label_position("left")
# Adjust location of axis/labels so they're not on top of the other dataset sharing that side of the chart
rspine.set_position(('axes', -0.05))
# Y-axis range
plt.ylim((-2, 2))
# Divide y-axis into 20 tick marks
plt.locator_params(axis = 'y', nbins = 20)
# Link data and color line
plot3.plot(systemData['Plot3'], color = 'limegreen', label = 'Plot3')
# Label and label color
plot3.set_ylabel('Plot3', color = 'limegreen')
## Plot4
# Create Plot4 sharing an X-axis with plot1 plot
plot4 = plot1.twinx()
# Display y-axis labels to the right of scale line
rspine = plot4.spines['right']
# Y-axis range
plt.ylim((-0.05, 0.5))
# Divide y-axis in to 10 ticks
plt.locator_params(axis = 'y', nbins = 10)
# Link data and color line
plot4.plot(systemData['Plot4'], color = 'r', label = 'Plot4')
# Label and label color
plot4.set_ylabel('Plot4', color = 'b')
## plot5
# Create Plot5 sharing an X-axis with plot1 plot
plot5 = plot1.twinx()
# Display ticks on left side of chart
plot5.yaxis.tick_left()
# Display tick labels to left of tick line
rspine = plot3.spines['left']
# Display y-axis label to the left of the chart
plot5.yaxis.set_label_position("left")
# Adjust location of axis/labels so they're not on top of the other dataset sharing that side of the chart
rspine.set_position(('axes', -0.05))
# Y-axis range
plt.ylim((7.0, 8.5))
# Display y-axis grid lines
plot5.yaxis.grid()
# Divide y-axis into 10 ticks
plt.locator_params(axis = 'y', nbins = 10)
# Link data and color line
# Raw
plot5.plot(systemData['Plot5'], color = 'r', label = 'Plot5')
# Label and label color
plot5.set_ylabel('Plot5', color = 'r')
## Overall chart formatting
# Format x-axis hour labels
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%I:%M %p'))
# Only tick on each hour
plt.gca().xaxis.set_major_locator(mdates.HourLocator(interval = 1))
# Display labels at an angle for space
fig.autofmt_xdate()
# Place legend below chart
fig.legend(loc = 'lower center', ncol = 5)
# Display final chart
plt.show()
report = Report()
report.runReport()
CodePudding user response:
This line:
# Limit x-axis to 00:00 - 23:59 range
plot1.set_xlim([datetime.date(2022,3,6), datetime.date(2022,3,7)])
Worked due to prototyping with a sample dataset with data from that date, and then partially failed due to failure to fully integrate. Self-flagellation will be brief.