Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions docs/examples/plot_ghi_transposition.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""
GHI to POA Transposition
=========================

Example of transposing clearsky GHI to POA
"""

# %%
# This example shows how to use the get_clearsky method to generate clearsky
# GHI data as well as how to use the get_total_iradiance function to transpose
# GHI data to Plane of Array (POA) irradiance.

from pvlib import location
from pvlib.irradiance import get_total_irradiance
import pandas as pd
from matplotlib import pyplot as plt

# For this example, we will be using Golden, Colorado
tz = 'MST'
lat, lon = 39.755, -105.221
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nice choice of location, +1


# Create location object to store lat, lon, timezone
site = location.Location(lat, lon, tz=tz)


# Define a function to handle the transposition
def get_irradiance(site_location, date, tilt, surface_azimuth):
# Creates one day's worth of 10 min intervals
times = pd.date_range(date, freq='10min', periods=6*24, tz=tz)
# Generate cleaersky data using the Ineichen model, which is the default
# The get_clearsky method returns a dataframe with values for GHI, DNI,
# and DHI
clearsky_ghi = site_location.get_clearsky(times)
# Get solar azimuth and zenith to pass to the transposition function
solar_position = site_location.get_solarposition(times=times)
# Use the get_total_irradiance function to transpose the GHI to POA
POA_irradiance = get_total_irradiance(
surface_tilt=tilt,
surface_azimuth=surface_azimuth,
dni=clearsky_ghi['dni'],
ghi=clearsky_ghi['ghi'],
dhi=clearsky_ghi['dhi'],
solar_zenith=solar_position['zenith'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
solar_zenith=solar_position['zenith'],
solar_zenith=solar_position['apparent_zenith'],

FYI I'd like someone else to confirm that using apparent solar position is appropriate before making this change

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the parameters for each transposition model option in get_total_irradiance, apparent_zenith should be passed through, rather than zenith.

It's a different matter to verify that each model actually expects apparent_zenith rather than zenith. I'll look at the underlying references when I can find the opportunity.

solar_azimuth=solar_position['azimuth'])
# Return DataFrame with only GHI and POA
return pd.DataFrame({'GHI': clearsky_ghi['ghi'],
'POA': POA_irradiance['poa_global']})


# Get irradiance data for summer and winter solstice, assuming 25 degree tilt
# and a south facing array
summer_irradiance = get_irradiance(site, '06-20-2020', 25, 180)
winter_irradiance = get_irradiance(site, '12-21-2020', 25, 180)

# Plot GHI vs. POA for winter and summer
fig, (ax1, ax2) = plt.subplots(1, 2)
Copy link
Member

@mikofski mikofski Mar 11, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example is really great! Thanks!

I have a minor suggestion, can you vertically stack the plots and share the x-axis?

fig, ax = plt.subplots(2, 1, sharex=True)  # stack plots (2, 1) and share the x axis
ax1, ax2 = ax  # or you can just use ax[0] instead of ax1, and ax[1] instead ax2, minor preference

I'm having a hard time reading the dates on the x-axis because they're a bit crowded, so I thought trying them vertical and sharing them might look nicer, but your call - but not a blocker for me - also fine as is, THANKS!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately the indexes are 6 months apart so I don't think sharex=True will look good. Could convert the datetime index to a nicer string form with df.index.strftime("%H:%M"). Or could drop sharex=True, but then the x-label for the upper axes might overlap the bottom axes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi Mike and Kevin! I am looking at this now- I agree the x-axis is a bit cluttered. I think the benefit of keeping the plots side-by-side is that it highlights that, while there is not much of a gain for POA compared to GHI in the summer, overall irradiance is higher.

I'll make some edits now and push up the new version!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're both right! Sorry for the distraction! Great work

summer_irradiance['GHI'].plot(ax=ax1, label='GHI')
summer_irradiance['POA'].plot(ax=ax1, label='POA')
winter_irradiance['GHI'].plot(ax=ax2, label='GHI')
winter_irradiance['POA'].plot(ax=ax2, label='POA')
ax1.set_xlabel('Time of day (Summer)')
ax2.set_xlabel('Time of day (Winter)')
ax1.set_ylabel('Irradiance (W/m2)')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can use latex here for W/m^2 if you want, it might look a little bit nicer?

ax1.set_ylabel('Irradiance ($W/m^2$)')

image
I also added gridlines, but I noticed other examples don't have them, so just my personal preference, dk what the convention is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback Mike! Made these changes and am uploading a new version now :)

ax2.set_ylabel('Irradiance (W/m2)')
ax1.legend()
ax2.legend()
plt.show()

# %%
# Note that in Summer, there is not much gain when comparing POA irradiance to
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for this note, answers a question often asked by newcomers to PV modeling

# GHI. In the winter, however, POA irradiance is signifiacntly higher than
# GHI. This is because, in winter, the sun is much lower in the sky, so a
# tilted array will be at a more optimal angle compared to a flat array.
# In summer, the sun gets much higher in the sky, and there is very little
# gain for a tilted array compared to a flat array.
2 changes: 2 additions & 0 deletions docs/sphinx/source/whatsnew/v0.7.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ Documentation
* Add example of IV curve generation. (:pull:`872`)
* Add section about gallery examples to Contributing guide. (:pull:`905`)
* Add section with link to Code of Conduct in Contributing guide. (:pull:`922`)
* Add example of GHI to POA transposition (:pull:`933`)

Requirements
~~~~~~~~~~~~
Expand All @@ -81,3 +82,4 @@ Contributors
* Kevin Anderson (:ghuser:`kanderso-nrel`)
* Karthikeyan Singaravelan (:ghuser:`tirkarthi`)
* Siyan (Veronica) Guo (:ghuser:`veronicaguo`)
* Eric Fitch (:ghuser:`ericf900`)