solarposition.py
tutorial¶This tutorial needs your help to make it better!
Table of contents:
This tutorial has been tested against the following package versions:
It should work with other Python and Pandas versions. It requires pvlib > 0.3.0 and IPython > 3.0.
Authors:
import datetime
# scientific python add-ons
import numpy as np
import pandas as pd
# plotting stuff
# first line makes the plots appear in the notebook
%matplotlib inline
import matplotlib.pyplot as plt
# finally, we import the pvlib library
import pvlib
import pvlib
from pvlib.location import Location
tus = Location(32.2, -111, 'US/Arizona', 700, 'Tucson')
print(tus)
golden = Location(39.742476, -105.1786, 'America/Denver', 1830, 'Golden')
print(golden)
golden_mst = Location(39.742476, -105.1786, 'MST', 1830, 'Golden MST')
print(golden_mst)
berlin = Location(52.5167, 13.3833, 'Europe/Berlin', 34, 'Berlin')
print(berlin)
Location: name: Tucson latitude: 32.2 longitude: -111 altitude: 700 tz: US/Arizona Location: name: Golden latitude: 39.742476 longitude: -105.1786 altitude: 1830 tz: America/Denver Location: name: Golden MST latitude: 39.742476 longitude: -105.1786 altitude: 1830 tz: MST Location: name: Berlin latitude: 52.5167 longitude: 13.3833 altitude: 34 tz: Europe/Berlin
times = pd.date_range(start=datetime.datetime(2014,6,23), end=datetime.datetime(2014,6,24), freq='1Min')
times_loc = times.tz_localize(tus.pytz)
times
DatetimeIndex(['2014-06-23 00:00:00', '2014-06-23 00:01:00', '2014-06-23 00:02:00', '2014-06-23 00:03:00', '2014-06-23 00:04:00', '2014-06-23 00:05:00', '2014-06-23 00:06:00', '2014-06-23 00:07:00', '2014-06-23 00:08:00', '2014-06-23 00:09:00', ... '2014-06-23 23:51:00', '2014-06-23 23:52:00', '2014-06-23 23:53:00', '2014-06-23 23:54:00', '2014-06-23 23:55:00', '2014-06-23 23:56:00', '2014-06-23 23:57:00', '2014-06-23 23:58:00', '2014-06-23 23:59:00', '2014-06-24 00:00:00'], dtype='datetime64[ns]', length=1441, freq='T')
pyephemout = pvlib.solarposition.pyephem(times_loc, tus.latitude, tus.longitude)
spaout = pvlib.solarposition.spa_python(times_loc, tus.latitude, tus.longitude)
pyephemout['elevation'].plot(label='pyephem')
pyephemout['apparent_elevation'].plot(label='pyephem apparent')
spaout['elevation'].plot(label='spa')
plt.legend(ncol=2)
plt.title('elevation')
print('pyephem')
print(pyephemout.head())
print('spa')
print(spaout.head())
pyephem apparent_elevation apparent_azimuth elevation \ 2014-06-23 00:00:00-07:00 -34.028887 352.757414 -34.028887 2014-06-23 00:01:00-07:00 -34.055060 353.032425 -34.055060 2014-06-23 00:02:00-07:00 -34.080223 353.307627 -34.080223 2014-06-23 00:03:00-07:00 -34.104374 353.583047 -34.104374 2014-06-23 00:04:00-07:00 -34.127518 353.858659 -34.127518 azimuth apparent_zenith zenith 2014-06-23 00:00:00-07:00 352.757414 124.028887 124.028887 2014-06-23 00:01:00-07:00 353.032425 124.055060 124.055060 2014-06-23 00:02:00-07:00 353.307627 124.080223 124.080223 2014-06-23 00:03:00-07:00 353.583047 124.104374 124.104374 2014-06-23 00:04:00-07:00 353.858659 124.127518 124.127518 spa apparent_zenith zenith apparent_elevation \ 2014-06-23 00:00:00-07:00 124.028842 124.028842 -34.028842 2014-06-23 00:01:00-07:00 124.055012 124.055012 -34.055012 2014-06-23 00:02:00-07:00 124.080175 124.080175 -34.080175 2014-06-23 00:03:00-07:00 124.104329 124.104329 -34.104329 2014-06-23 00:04:00-07:00 124.127471 124.127471 -34.127471 elevation azimuth equation_of_time 2014-06-23 00:00:00-07:00 -34.028842 352.757345 -2.150130 2014-06-23 00:01:00-07:00 -34.055012 353.032330 -2.150281 2014-06-23 00:02:00-07:00 -34.080175 353.307536 -2.150431 2014-06-23 00:03:00-07:00 -34.104329 353.582953 -2.150582 2014-06-23 00:04:00-07:00 -34.127471 353.858574 -2.150733
plt.figure()
pyephemout['elevation'].plot(label='pyephem')
spaout['elevation'].plot(label='spa')
(pyephemout['elevation'] - spaout['elevation']).plot(label='diff')
plt.legend(ncol=3)
plt.title('elevation')
plt.figure()
pyephemout['apparent_elevation'].plot(label='pyephem apparent')
spaout['elevation'].plot(label='spa')
(pyephemout['apparent_elevation'] - spaout['elevation']).plot(label='diff')
plt.legend(ncol=3)
plt.title('elevation')
plt.figure()
pyephemout['apparent_zenith'].plot(label='pyephem apparent')
spaout['zenith'].plot(label='spa')
(pyephemout['apparent_zenith'] - spaout['zenith']).plot(label='diff')
plt.legend(ncol=3)
plt.title('zenith')
plt.figure()
pyephemout['apparent_azimuth'].plot(label='pyephem apparent')
spaout['azimuth'].plot(label='spa')
(pyephemout['apparent_azimuth'] - spaout['azimuth']).plot(label='diff')
plt.legend(ncol=3)
plt.title('azimuth')
Text(0.5,1,'azimuth')
pyephemout = pvlib.solarposition.pyephem(times.tz_localize(golden.tz), golden.latitude, golden.longitude)
spaout = pvlib.solarposition.spa_python(times.tz_localize(golden.tz), golden.latitude, golden.longitude)
pyephemout['elevation'].plot(label='pyephem')
pyephemout['apparent_elevation'].plot(label='pyephem apparent')
spaout['elevation'].plot(label='spa')
plt.legend(ncol=2)
plt.title('elevation')
print('pyephem')
print(pyephemout.head())
print('spa')
print(spaout.head())
pyephem apparent_elevation apparent_azimuth elevation \ 2014-06-23 00:00:00-06:00 -25.154820 344.064195 -25.154820 2014-06-23 00:01:00-06:00 -25.207201 344.310956 -25.207201 2014-06-23 00:02:00-06:00 -25.258784 344.558018 -25.258784 2014-06-23 00:03:00-06:00 -25.309568 344.805380 -25.309568 2014-06-23 00:04:00-06:00 -25.359550 345.053043 -25.359550 azimuth apparent_zenith zenith 2014-06-23 00:00:00-06:00 344.064195 115.154820 115.154820 2014-06-23 00:01:00-06:00 344.310956 115.207201 115.207201 2014-06-23 00:02:00-06:00 344.558018 115.258784 115.258784 2014-06-23 00:03:00-06:00 344.805380 115.309568 115.309568 2014-06-23 00:04:00-06:00 345.053043 115.359550 115.359550 spa apparent_zenith zenith apparent_elevation \ 2014-06-23 00:00:00-06:00 115.154766 115.154766 -25.154766 2014-06-23 00:01:00-06:00 115.207146 115.207146 -25.207146 2014-06-23 00:02:00-06:00 115.258730 115.258730 -25.258730 2014-06-23 00:03:00-06:00 115.309514 115.309514 -25.309514 2014-06-23 00:04:00-06:00 115.359497 115.359497 -25.359497 elevation azimuth equation_of_time 2014-06-23 00:00:00-06:00 -25.154766 344.064134 -2.141078 2014-06-23 00:01:00-06:00 -25.207146 344.310880 -2.141229 2014-06-23 00:02:00-06:00 -25.258730 344.557936 -2.141380 2014-06-23 00:03:00-06:00 -25.309514 344.805299 -2.141531 2014-06-23 00:04:00-06:00 -25.359497 345.052965 -2.141682
pyephemout = pvlib.solarposition.pyephem(times.tz_localize(golden.tz), golden.latitude, golden.longitude)
ephemout = pvlib.solarposition.ephemeris(times.tz_localize(golden.tz), golden.latitude, golden.longitude)
pyephemout['elevation'].plot(label='pyephem')
pyephemout['apparent_elevation'].plot(label='pyephem apparent')
ephemout['elevation'].plot(label='ephem')
plt.legend(ncol=2)
plt.title('elevation')
print('pyephem')
print(pyephemout.head())
print('ephem')
print(ephemout.head())
pyephem apparent_elevation apparent_azimuth elevation \ 2014-06-23 00:00:00-06:00 -25.154820 344.064195 -25.154820 2014-06-23 00:01:00-06:00 -25.207201 344.310956 -25.207201 2014-06-23 00:02:00-06:00 -25.258784 344.558018 -25.258784 2014-06-23 00:03:00-06:00 -25.309568 344.805380 -25.309568 2014-06-23 00:04:00-06:00 -25.359550 345.053043 -25.359550 azimuth apparent_zenith zenith 2014-06-23 00:00:00-06:00 344.064195 115.154820 115.154820 2014-06-23 00:01:00-06:00 344.310956 115.207201 115.207201 2014-06-23 00:02:00-06:00 344.558018 115.258784 115.258784 2014-06-23 00:03:00-06:00 344.805380 115.309568 115.309568 2014-06-23 00:04:00-06:00 345.053043 115.359550 115.359550 ephem apparent_elevation elevation azimuth \ 2014-06-23 00:00:00-06:00 -25.149499 -25.149499 344.061394 2014-06-23 00:01:00-06:00 -25.201890 -25.201890 344.308126 2014-06-23 00:02:00-06:00 -25.253483 -25.253483 344.555170 2014-06-23 00:03:00-06:00 -25.304277 -25.304277 344.802520 2014-06-23 00:04:00-06:00 -25.354270 -25.354270 345.050172 apparent_zenith zenith solar_time 2014-06-23 00:00:00-06:00 115.149499 115.149499 22.952125 2014-06-23 00:01:00-06:00 115.201890 115.201890 22.968789 2014-06-23 00:02:00-06:00 115.253483 115.253483 22.985453 2014-06-23 00:03:00-06:00 115.304277 115.304277 23.002118 2014-06-23 00:04:00-06:00 115.354270 115.354270 23.018782
loc = berlin
pyephemout = pvlib.solarposition.pyephem(times.tz_localize(loc.tz), loc.latitude, loc.longitude)
ephemout = pvlib.solarposition.ephemeris(times.tz_localize(loc.tz), loc.latitude, loc.longitude)
pyephemout['elevation'].plot(label='pyephem')
pyephemout['apparent_elevation'].plot(label='pyephem apparent')
ephemout['elevation'].plot(label='ephem')
ephemout['apparent_elevation'].plot(label='ephem apparent')
plt.legend(ncol=2)
plt.title('elevation')
print('pyephem')
print(pyephemout.head())
print('ephem')
print(ephemout.head())
pyephem apparent_elevation apparent_azimuth elevation \ 2014-06-23 00:00:00+02:00 -12.598822 343.918876 -12.598822 2014-06-23 00:01:00+02:00 -12.640668 344.149982 -12.640668 2014-06-23 00:02:00+02:00 -12.681923 344.381225 -12.681923 2014-06-23 00:03:00+02:00 -12.722587 344.612605 -12.722587 2014-06-23 00:04:00+02:00 -12.762658 344.844121 -12.762658 azimuth apparent_zenith zenith 2014-06-23 00:00:00+02:00 343.918876 102.598822 102.598822 2014-06-23 00:01:00+02:00 344.149982 102.640668 102.640668 2014-06-23 00:02:00+02:00 344.381225 102.681923 102.681923 2014-06-23 00:03:00+02:00 344.612605 102.722587 102.722587 2014-06-23 00:04:00+02:00 344.844121 102.762658 102.762658 ephem apparent_elevation elevation azimuth \ 2014-06-23 00:00:00+02:00 -12.593452 -12.593452 343.916041 2014-06-23 00:01:00+02:00 -12.635306 -12.635306 344.147120 2014-06-23 00:02:00+02:00 -12.676569 -12.676569 344.378348 2014-06-23 00:03:00+02:00 -12.717240 -12.717240 344.609723 2014-06-23 00:04:00+02:00 -12.757320 -12.757320 344.841244 apparent_zenith zenith solar_time 2014-06-23 00:00:00+02:00 102.593452 102.593452 22.857453 2014-06-23 00:01:00+02:00 102.635306 102.635306 22.874117 2014-06-23 00:02:00+02:00 102.676569 102.676569 22.890781 2014-06-23 00:03:00+02:00 102.717240 102.717240 22.907446 2014-06-23 00:04:00+02:00 102.757320 102.757320 22.924110
loc = berlin
times = pd.DatetimeIndex(start=datetime.date(2015,3,28), end=datetime.date(2015,3,29), freq='5min')
pyephemout = pvlib.solarposition.pyephem(times.tz_localize(loc.tz), loc.latitude, loc.longitude)
ephemout = pvlib.solarposition.ephemeris(times.tz_localize(loc.tz), loc.latitude, loc.longitude)
pyephemout['elevation'].plot(label='pyephem')
pyephemout['apparent_elevation'].plot(label='pyephem apparent')
ephemout['elevation'].plot(label='ephem')
plt.legend(ncol=2)
plt.title('elevation')
plt.figure()
pyephemout['azimuth'].plot(label='pyephem')
ephemout['azimuth'].plot(label='ephem')
plt.legend(ncol=2)
plt.title('azimuth')
print('pyephem')
print(pyephemout.head())
print('ephem')
print(ephemout.head())
pyephem apparent_elevation apparent_azimuth elevation \ 2015-03-28 00:00:00+01:00 -34.669825 356.421155 -34.669825 2015-03-28 00:05:00+01:00 -34.705895 357.939260 -34.705895 2015-03-28 00:10:00+01:00 -34.721813 359.458321 -34.721813 2015-03-28 00:15:00+01:00 -34.717561 0.977630 -34.717561 2015-03-28 00:20:00+01:00 -34.693143 2.496380 -34.693143 azimuth apparent_zenith zenith 2015-03-28 00:00:00+01:00 356.421155 124.669825 124.669825 2015-03-28 00:05:00+01:00 357.939260 124.705895 124.705895 2015-03-28 00:10:00+01:00 359.458321 124.721813 124.721813 2015-03-28 00:15:00+01:00 0.977630 124.717561 124.717561 2015-03-28 00:20:00+01:00 2.496380 124.693143 124.693143 ephem apparent_elevation elevation azimuth \ 2015-03-28 00:00:00+01:00 -34.667077 -34.667077 356.419216 2015-03-28 00:05:00+01:00 -34.703175 -34.703175 357.937292 2015-03-28 00:10:00+01:00 -34.719120 -34.719120 359.456355 2015-03-28 00:15:00+01:00 -34.714893 -34.714893 0.975640 2015-03-28 00:20:00+01:00 -34.690500 -34.690500 2.494378 apparent_zenith zenith solar_time 2015-03-28 00:00:00+01:00 124.667077 124.667077 23.803474 2015-03-28 00:05:00+01:00 124.703175 124.703175 23.886825 2015-03-28 00:10:00+01:00 124.719120 124.719120 23.970175 2015-03-28 00:15:00+01:00 124.714893 124.714893 0.053526 2015-03-28 00:20:00+01:00 124.690500 124.690500 0.136877
loc = berlin
times = pd.DatetimeIndex(start=datetime.date(2015,3,30), end=datetime.date(2015,3,31), freq='5min')
pyephemout = pvlib.solarposition.pyephem(times.tz_localize(loc.tz), loc.latitude, loc.longitude)
ephemout = pvlib.solarposition.ephemeris(times.tz_localize(loc.tz), loc.latitude, loc.longitude)
pyephemout['elevation'].plot(label='pyephem')
pyephemout['apparent_elevation'].plot(label='pyephem apparent')
ephemout['elevation'].plot(label='ephem')
plt.legend(ncol=2)
plt.title('elevation')
plt.figure()
pyephemout['azimuth'].plot(label='pyephem')
ephemout['azimuth'].plot(label='ephem')
plt.legend(ncol=2)
plt.title('azimuth')
print('pyephem')
print(pyephemout.head())
print('ephem')
print(ephemout.head())
pyephem apparent_elevation apparent_azimuth elevation \ 2015-03-30 00:00:00+02:00 -31.976429 338.920871 -31.976429 2015-03-30 00:05:00+02:00 -32.239797 340.360894 -32.239797 2015-03-30 00:10:00+02:00 -32.485100 341.809413 -32.485100 2015-03-30 00:15:00+02:00 -32.712074 343.265937 -32.712074 2015-03-30 00:20:00+02:00 -32.920477 344.729920 -32.920477 azimuth apparent_zenith zenith 2015-03-30 00:00:00+02:00 338.920871 121.976429 121.976429 2015-03-30 00:05:00+02:00 340.360894 122.239797 122.239797 2015-03-30 00:10:00+02:00 341.809413 122.485100 122.485100 2015-03-30 00:15:00+02:00 343.265937 122.712074 122.712074 2015-03-30 00:20:00+02:00 344.729920 122.920477 122.920477 ephem apparent_elevation elevation azimuth \ 2015-03-30 00:00:00+02:00 -31.973191 -31.973191 338.919052 2015-03-30 00:05:00+02:00 -32.236587 -32.236587 340.359056 2015-03-30 00:10:00+02:00 -32.481918 -32.481918 341.807546 2015-03-30 00:15:00+02:00 -32.708921 -32.708921 343.264033 2015-03-30 00:20:00+02:00 -32.917353 -32.917353 344.727991 apparent_zenith zenith solar_time 2015-03-30 00:00:00+02:00 121.973191 121.973191 22.813319 2015-03-30 00:05:00+02:00 122.236587 122.236587 22.896670 2015-03-30 00:10:00+02:00 122.481918 122.481918 22.980021 2015-03-30 00:15:00+02:00 122.708921 122.708921 23.063372 2015-03-30 00:20:00+02:00 122.917353 122.917353 23.146722
loc = berlin
times = pd.DatetimeIndex(start=datetime.date(2015,6,28), end=datetime.date(2015,6,29), freq='5min')
pyephemout = pvlib.solarposition.pyephem(times.tz_localize(loc.tz), loc.latitude, loc.longitude)
ephemout = pvlib.solarposition.ephemeris(times.tz_localize(loc.tz), loc.latitude, loc.longitude)
pyephemout['elevation'].plot(label='pyephem')
pyephemout['apparent_elevation'].plot(label='pyephem apparent')
ephemout['elevation'].plot(label='ephem')
plt.legend(ncol=2)
plt.title('elevation')
plt.figure()
pyephemout['azimuth'].plot(label='pyephem')
ephemout['azimuth'].plot(label='ephem')
plt.legend(ncol=2)
plt.title('azimuth')
print('pyephem')
print(pyephemout.head())
print('ephem')
print(ephemout.head())
pyephem apparent_elevation apparent_azimuth elevation \ 2015-06-28 00:00:00+02:00 -12.679250 343.659411 -12.679250 2015-06-28 00:05:00+02:00 -12.885989 344.817210 -12.885989 2015-06-28 00:10:00+02:00 -13.077872 345.978615 -13.077872 2015-06-28 00:15:00+02:00 -13.254779 347.143381 -13.254779 2015-06-28 00:20:00+02:00 -13.416591 348.311289 -13.416591 azimuth apparent_zenith zenith 2015-06-28 00:00:00+02:00 343.659411 102.679250 102.679250 2015-06-28 00:05:00+02:00 344.817210 102.885989 102.885989 2015-06-28 00:10:00+02:00 345.978615 103.077872 103.077872 2015-06-28 00:15:00+02:00 347.143381 103.254779 103.254779 2015-06-28 00:20:00+02:00 348.311289 103.416591 103.416591 ephem apparent_elevation elevation azimuth \ 2015-06-28 00:00:00+02:00 -12.674183 -12.674183 343.658144 2015-06-28 00:05:00+02:00 -12.880940 -12.880940 344.815897 2015-06-28 00:10:00+02:00 -13.072843 -13.072843 345.977260 2015-06-28 00:15:00+02:00 -13.249769 -13.249769 347.141996 2015-06-28 00:20:00+02:00 -13.411601 -13.411601 348.309859 apparent_zenith zenith solar_time 2015-06-28 00:00:00+02:00 102.674183 102.674183 22.840578 2015-06-28 00:05:00+02:00 102.880940 102.880940 22.923900 2015-06-28 00:10:00+02:00 103.072843 103.072843 23.007221 2015-06-28 00:15:00+02:00 103.249769 103.249769 23.090542 2015-06-28 00:20:00+02:00 103.411601 103.411601 23.173864
pyephemout['elevation'].plot(label='pyephem')
pyephemout['apparent_elevation'].plot(label='pyephem apparent')
ephemout['elevation'].plot(label='ephem')
ephemout['apparent_elevation'].plot(label='ephem apparent')
plt.legend(ncol=2)
plt.title('elevation')
plt.xlim(pd.Timestamp('2015-06-28 02:00:00+02:00'), pd.Timestamp('2015-06-28 06:00:00+02:00'))
plt.ylim(-10,10)
(-10, 10)
times_loc = times.tz_localize(loc.tz)
%%timeit
pyephemout = pvlib.solarposition.pyephem(times_loc, loc.latitude, loc.longitude)
#ephemout = pvlib.solarposition.ephemeris(times, loc)
13.3 ms ± 377 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%timeit
#pyephemout = pvlib.solarposition.pyephem(times, loc)
ephemout = pvlib.solarposition.ephemeris(times_loc, loc.latitude, loc.longitude)
15.4 ms ± 923 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%%timeit
#pyephemout = pvlib.solarposition.pyephem(times, loc)
ephemout = pvlib.solarposition.get_solarposition(times_loc, loc.latitude, loc.longitude,
method='nrel_numpy')
11.2 ms ± 696 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
This numba test will only work properly if you have installed numba.
%%timeit
#pyephemout = pvlib.solarposition.pyephem(times, loc)
ephemout = pvlib.solarposition.get_solarposition(times_loc, loc.latitude, loc.longitude,
method='nrel_numba')
1.6 ms ± 150 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
The numba calculation takes a long time the first time that it's run because it uses LLVM to compile the Python code to machine code. After that it's about 4-10 times faster depending on your machine. You can pass a numthreads
argument to this function. The optimum numthreads
depends on your machine and is equal to 4 by default.
%%timeit
#pyephemout = pvlib.solarposition.pyephem(times, loc)
ephemout = pvlib.solarposition.get_solarposition(times_loc, loc.latitude, loc.longitude,
method='nrel_numba', numthreads=16)
2.52 ms ± 424 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%%timeit
ephemout = pvlib.solarposition.spa_python(times_loc, loc.latitude, loc.longitude,
how='numba', numthreads=16)
2.58 ms ± 389 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)