Plot power curves for all 25 turbines#

import itertools

import matplotlib.pyplot as plt
import pandas as pd
# configure plot styles
plt.style.use("seaborn-colorblind")
plt.rcParams["font.family"] = "Source Sans Pro"
plt.rcParams["figure.dpi"] = 96
plt.rcParams["axes.grid"] = False
plt.rcParams["figure.titleweight"] = "semibold"
plt.rcParams["axes.titleweight"] = "semibold"
plt.rcParams["figure.titlesize"] = "13"
plt.rcParams["axes.titlesize"] = "12"
plt.rcParams["axes.labelsize"] = "10"
# create dataframe from CSV
data = pd.read_csv(
    "data/processed/SCADA_timeseries.csv", skip_blank_lines=True
)
# create pivot table (new dataframe)
power = pd.pivot_table(
    data, index=["ws_av"], columns=["turbine"], values=["ap_av"]
)
# removing pivot table values name from heading
power.columns = power.columns.droplevel(0)
# rename index (x-axis title)
power.index.name = "Wind speed (m/s)"
power
turbine 1 2 3 4 5 6 7 8 9 10 ... 16 17 18 19 20 21 22 23 24 25
Wind speed (m/s)
0.000000 0.0 0.0 0.0 0.0 0.0 0.050226 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.000007 0.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
0.000007 NaN NaN NaN NaN NaN 0.000000 NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
0.000007 NaN NaN NaN NaN NaN 0.000000 NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
0.000007 0.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
36.467920 NaN NaN NaN NaN 0.0 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
36.558680 NaN NaN NaN NaN 0.0 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
37.271650 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN 0.0 NaN NaN NaN NaN NaN NaN NaN NaN
37.332910 NaN NaN NaN NaN 0.0 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
37.413030 NaN NaN 0.0 NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

2641616 rows × 25 columns

# get coordinates of each subplot
layout = list(range(0, 5))
coord = list(itertools.product(layout, layout))

# list of column headers (i.e. turbines 1 to 25)
cols = list(power)

Standard power curves#

# plotting all columns (i.e. turbines 1 to 25) in the same figure
fig, axs = plt.subplots(ncols=5, nrows=5, figsize=(50, 30))

for (x, y), col in zip(coord, cols):
    axs[x, y].scatter(x=power.index, y=power[col], marker=".", c="C" + str(y))
    axs[x, y].set_title("Power curve for turbine " + str(col))
    axs[x, y].set_xlabel("Wind speed (m/s)")
    axs[x, y].set_ylabel("Average active power (kW)")

fig.tight_layout()
plt.show()
../../_images/9d4b03989d0b8c08c090a8945a24efcbab8cfe394ff76dbb3c75a86720bf4abf.png

Normalised power curves#

# normalise using feature scaling (all values in the range [0, 1])
power_norm = (power - power.min()) / (power.max() - power.min())
power_norm.index = (power.index - power.index.min()) / (
    power.index.max() - power.index.min()
)
# rename index
power_norm.index.name = "Wind speed"
fig, axs = plt.subplots(ncols=5, nrows=5, figsize=(50, 30))

for (x, y), col in zip(coord, cols):
    axs[x, y].scatter(
        x=power_norm.index, y=power_norm[col], marker=".", c="C" + str(y)
    )
    axs[x, y].set_title("Normalised power curve for turbine " + str(col))
    axs[x, y].set_xlabel("Wind speed")
    axs[x, y].set_ylabel("Average active power")

fig.tight_layout()
plt.show()
../../_images/f9e22225f39b46f3e51fac97ddce2e45c9e25ad8c05ebe0a2315e0ed2c28a81c.png

Rotor speed vs power#

# create pivot table (new dataframe)
power = pd.pivot_table(
    data, index=["rs_av"], columns=["turbine"], values=["ap_av"]
)
# removing pivot table values name from heading
power.columns = power.columns.droplevel(0)
# rename index
power.index.name = "Rotor speed (rpm)"
# plotting all columns (i.e. turbines 1 to 25) in the same figure
fig, axs = plt.subplots(ncols=5, nrows=5, figsize=(50, 30))

for (x, y), col in zip(coord, cols):
    axs[x, y].scatter(x=power.index, y=power[col], marker=".", c="C" + str(y))
    axs[x, y].set_title(
        "Average active power vs rotor speed for turbine " + str(col)
    )
    axs[x, y].set_xlabel("Rotor speed (rpm)")
    axs[x, y].set_ylabel("Average active power (kW)")

fig.tight_layout()
plt.show()
../../_images/bc912348aa0fb16e605e397c697756da28d87f26985352f8cf0d33b908c2df44.png

Power vs pitch angle#

# create pivot table (new dataframe)
power = pd.pivot_table(
    data, index=["ap_av"], columns=["turbine"], values=["pitch"]
)
# removing pivot table values name from heading
power.columns = power.columns.droplevel(0)
# rename index
power.index.name = "Average active power (kW)"
# plotting all columns (i.e. turbines 1 to 25) in the same figure
fig, axs = plt.subplots(ncols=5, nrows=5, figsize=(50, 30))

for (x, y), col in zip(coord, cols):
    axs[x, y].scatter(x=power.index, y=power[col], marker=".", c="C" + str(y))
    axs[x, y].set_title(
        "Pitch angle vs average active power for turbine " + str(col)
    )
    axs[x, y].set_xlabel("Average active power (kW)")
    axs[x, y].set_ylabel("Pitch angle (deg)")

fig.tight_layout()
plt.show()
../../_images/a3669afc8bcbeb2398d9389a8f5bc60e8deeadf196c004d44ce176ad480ff7ec.png