{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\nSun path diagram\n================\n\nExamples of generating sunpath diagrams.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "This example shows basic usage of pvlib's solar position calculations with\n:py:meth:`pvlib.solarposition.get_solarposition`.  The examples shown here\nwill generate sunpath diagrams that shows solar position over a year.\n\nPolar plot\n----------\n\nBelow is an example plot of solar position in\n`polar coordinates <https://en.wikipedia.org/wiki/Polar_coordinate_system>`_.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from pvlib import solarposition\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\n\ntz = 'Asia/Calcutta'\nlat, lon = 28.6, 77.2\n\ntimes = pd.date_range('2019-01-01 00:00:00', '2020-01-01', closed='left',\n                      freq='H', tz=tz)\nsolpos = solarposition.get_solarposition(times, lat, lon)\n# remove nighttime\nsolpos = solpos.loc[solpos['apparent_elevation'] > 0, :]\n\nax = plt.subplot(1, 1, 1, projection='polar')\n# draw the analemma loops\npoints = ax.scatter(np.radians(solpos.azimuth), solpos.apparent_zenith,\n                    s=2, label=None, c=solpos.index.dayofyear)\nax.figure.colorbar(points)\n\n# draw hour labels\nfor hour in np.unique(solpos.index.hour):\n    # choose label position by the smallest radius for each hour\n    subset = solpos.loc[solpos.index.hour == hour, :]\n    r = subset.apparent_zenith\n    pos = solpos.loc[r.idxmin(), :]\n    ax.text(np.radians(pos['azimuth']), pos['apparent_zenith'], str(hour))\n\n# draw individual days\nfor date in pd.to_datetime(['2019-03-21', '2019-06-21', '2019-12-21']):\n    times = pd.date_range(date, date+pd.Timedelta('24h'), freq='5min', tz=tz)\n    solpos = solarposition.get_solarposition(times, lat, lon)\n    solpos = solpos.loc[solpos['apparent_elevation'] > 0, :]\n    label = date.strftime('%Y-%m-%d')\n    ax.plot(np.radians(solpos.azimuth), solpos.apparent_zenith, label=label)\n\nax.figure.legend(loc='upper left')\n\n# change coordinates to be like a compass\nax.set_theta_zero_location('N')\nax.set_theta_direction(-1)\nax.set_rmax(90)\n\nplt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "This is a polar plot of hourly solar zenith and azimuth. The figure-8\npatterns are called `analemmas <https://en.wikipedia.org/wiki/Analemma>`_ and\nshow how the sun's path slowly shifts over the course of the year .  The\ncolored lines show the single-day sun paths for the winter and summer\nsolstices as well as the spring equinox.\n\nThe soltice paths mark the boundary of the sky area that the sun traverses\nover a year.  The diagram shows that there is no point in the\nyear when is the sun directly overhead (zenith=0) -- note that this location\nis north of the Tropic of Cancer.\n\nExamining the sun path for the summer solstice in particular shows that\nthe sun rises north of east, crosses into the southern sky around 10 AM for a\nfew hours before crossing back into the northern sky around 3 PM and setting\nnorth of west.  In contrast, the winter solstice sun path remains in the\nsouthern sky the entire day.  Moreover, the diagram shows that the winter\nsolstice is a shorter day than the summer soltice -- in December, the sun\nrises after 7 AM and sets before 6 PM, whereas in June the sun is up before\n6 AM and sets after 7 PM.\n\nAnother use of this diagram is to determine what times of year the sun is\nblocked by obstacles. For instance, for a mountain range on the western side\nof an array that extends 10 degrees above the horizon, the sun is blocked:\n\n- after about 6:30 PM on the summer solstice\n- after about 5:30 PM on the spring equinox\n- after about 4:30 PM on the winter solstice\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "PVSyst Plot\n-----------\n\nPVSyst users will be more familiar with sunpath diagrams in Cartesian\ncoordinates:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from pvlib import solarposition\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\n\ntz = 'Asia/Calcutta'\nlat, lon = 28.6, 77.2\ntimes = pd.date_range('2019-01-01 00:00:00', '2020-01-01', closed='left',\n                      freq='H', tz=tz)\n\nsolpos = solarposition.get_solarposition(times, lat, lon)\n# remove nighttime\nsolpos = solpos.loc[solpos['apparent_elevation'] > 0, :]\n\nfig, ax = plt.subplots()\npoints = ax.scatter(solpos.azimuth, solpos.apparent_elevation, s=2,\n                    c=solpos.index.dayofyear, label=None)\nfig.colorbar(points)\n\nfor hour in np.unique(solpos.index.hour):\n    # choose label position by the largest elevation for each hour\n    subset = solpos.loc[solpos.index.hour == hour, :]\n    height = subset.apparent_elevation\n    pos = solpos.loc[height.idxmax(), :]\n    ax.text(pos['azimuth'], pos['apparent_elevation'], str(hour))\n\nfor date in pd.to_datetime(['2019-03-21', '2019-06-21', '2019-12-21']):\n    times = pd.date_range(date, date+pd.Timedelta('24h'), freq='5min', tz=tz)\n    solpos = solarposition.get_solarposition(times, lat, lon)\n    solpos = solpos.loc[solpos['apparent_elevation'] > 0, :]\n    label = date.strftime('%Y-%m-%d')\n    ax.plot(solpos.azimuth, solpos.apparent_elevation, label=label)\n\nax.figure.legend(loc='upper left')\nax.set_xlabel('Solar Azimuth (degrees)')\nax.set_ylabel('Solar Elevation (degrees)')\n\nplt.show()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.7.3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}