Intro Examples¶
This page contains introductory examples of pvlib python usage.
Modeling paradigms¶
The backbone of pvlib-python is well-tested procedural code that implements PV system models. pvlib-python also provides a collection of classes for users that prefer object-oriented programming. These classes can help users keep track of data in a more organized way, provide some “smart” functions with more flexible inputs, and simplify the modeling process for common situations. The classes do not add any algorithms beyond what’s available in the procedural code, and most of the object methods are simple wrappers around the corresponding procedural code.
Let’s use each of these pvlib modeling paradigms to calculate the yearly energy yield for a given hardware configuration at a handful of sites listed below.
In [1]: import pandas as pd
In [2]: import matplotlib.pyplot as plt
In [3]: naive_times = pd.DatetimeIndex(start='2015', end='2016', freq='1h')
# very approximate
# latitude, longitude, name, altitude, timezone
In [4]: coordinates = [(30, -110, 'Tucson', 700, 'Etc/GMT+7'),
...: (35, -105, 'Albuquerque', 1500, 'Etc/GMT+7'),
...: (40, -120, 'San Francisco', 10, 'Etc/GMT+8'),
...: (50, 10, 'Berlin', 34, 'Etc/GMT-1')]
...:
In [5]: import pvlib
# get the module and inverter specifications from SAM
In [6]: sandia_modules = pvlib.pvsystem.retrieve_sam('SandiaMod')
In [7]: sapm_inverters = pvlib.pvsystem.retrieve_sam('cecinverter')
In [8]: module = sandia_modules['Canadian_Solar_CS5P_220M___2009_']
In [9]: inverter = sapm_inverters['ABB__MICRO_0_25_I_OUTD_US_208_208V__CEC_2014_']
# specify constant ambient air temp and wind for simplicity
In [10]: temp_air = 20
In [11]: wind_speed = 0
Procedural¶
The straightforward procedural code can be used for all modeling steps in pvlib-python.
The following code demonstrates how to use the procedural code to accomplish our system modeling goal:
In [12]: system = {'module': module, 'inverter': inverter,
....: 'surface_azimuth': 180}
....:
In [13]: energies = {}
In [14]: for latitude, longitude, name, altitude, timezone in coordinates:
....: times = naive_times.tz_localize(timezone)
....: system['surface_tilt'] = latitude
....: solpos = pvlib.solarposition.get_solarposition(times, latitude, longitude)
....: dni_extra = pvlib.irradiance.get_extra_radiation(times)
....: airmass = pvlib.atmosphere.get_relative_airmass(solpos['apparent_zenith'])
....: pressure = pvlib.atmosphere.alt2pres(altitude)
....: am_abs = pvlib.atmosphere.get_absolute_airmass(airmass, pressure)
....: tl = pvlib.clearsky.lookup_linke_turbidity(times, latitude, longitude)
....: cs = pvlib.clearsky.ineichen(solpos['apparent_zenith'], am_abs, tl,
....: dni_extra=dni_extra, altitude=altitude)
....: aoi = pvlib.irradiance.aoi(system['surface_tilt'], system['surface_azimuth'],
....: solpos['apparent_zenith'], solpos['azimuth'])
....: total_irrad = pvlib.irradiance.get_total_irradiance(system['surface_tilt'],
....: system['surface_azimuth'],
....: solpos['apparent_zenith'],
....: solpos['azimuth'],
....: cs['dni'], cs['ghi'], cs['dhi'],
....: dni_extra=dni_extra,
....: model='haydavies')
....: temps = pvlib.pvsystem.sapm_celltemp(total_irrad['poa_global'],
....: wind_speed, temp_air)
....: effective_irradiance = pvlib.pvsystem.sapm_effective_irradiance(
....: total_irrad['poa_direct'], total_irrad['poa_diffuse'],
....: am_abs, aoi, module)
....: dc = pvlib.pvsystem.sapm(effective_irradiance, temps['temp_cell'], module)
....: ac = pvlib.pvsystem.snlinverter(dc['v_mp'], dc['p_mp'], inverter)
....: annual_energy = ac.sum()
....: energies[name] = annual_energy
....:
In [15]: energies = pd.Series(energies)
# based on the parameters specified above, these are in W*hrs
In [16]: print(energies.round(0))
Albuquerque 500451.0
Berlin 383547.0
San Francisco 440046.0
Tucson 467740.0
dtype: float64
In [17]: energies.plot(kind='bar', rot=0)