Completed
Push — dev ( 68ddc7...49e927 )
by Patrik
58s queued 48s
created

plots_grids.hex_from_rgb()   A

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nop 1
1
import os
2
import matplotlib.colors as mcolors
3
import matplotlib.pyplot as plt
4
import numpy as np
5
import pandas as pd
6
7
# creates the icons in the grid view of the documentation
8
9
10
def hex_from_rgb(rgb):
11
    """makes rgb to hex"""
12
    return "#{:02X}{:02X}{:02X}".format(
13
        int(rgb[0] * 255), int(rgb[1] * 255), int(rgb[2] * 255)
14
    )
15
16
17
# colors of the color palette
18
dark_palette = {
19
    "color1": "#1F567D",
20
    "color2": "#8AA8A1",
21
    "color3": "#FA8334",
22
    "color4": "#FF006E",
23
    "color5": "#FFFD77",
24
}
25
26
# crates light mode color palet
27
light_palette = {"color1": dark_palette["color1"]}
28
for key in ["color2", "color3", "color4", "color5"]:
29
    rgb = mcolors.to_rgb(dark_palette[key])
30
    new_rgb = [0.7 * c + 0.3 for c in rgb]
31
    light_palette[key] = hex_from_rgb(new_rgb)
32
33
34
def draw_lin_vs_mixed_int(mode="dark"):
35
    """
36
    draws plot for the linear optimization vs. Mix Integer section
37
    """
38
    if mode == "dark":
39
        palette = dark_palette
40
        bg_color = "#121212"
41
        text_color = "#FFFFFF"
42
    else:
43
        palette = light_palette
44
        bg_color = "#FFFFFF"
45
        text_color = "#000000"
46
47
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
48
    fig.patch.set_facecolor(bg_color)
49
50
    for ax in [ax1, ax2]:
51
        ax.set_facecolor(bg_color)
52
        ax.tick_params(colors=text_color)
53
        for spine in ax.spines.values():
54
            spine.set_color(text_color)
55
56
    # linear function
57
    x = np.linspace(-10, 10, 400)
58
    y = 2 * x + 1
59
    ax1.plot(x, y, color=palette["color1"], linewidth=2)
60
    ax1.set_title("Linear Programming", color=text_color, fontsize=14)
61
    ax1.set_xticks([])
62
    ax1.set_yticks([])
63
64
    # function including a jump
65
    x_left = np.linspace(-10, -0.01, 200)
66
    x_right = np.linspace(0, 10, 200)
67
    y_left = 2 * x_left + 1
68
    y_right = 2 * x_right + 1 + 5
69
70
    ax2.plot(x_left, y_left, color=palette["color1"], linewidth=2)
71
    ax2.plot(x_right, y_right, color=palette["color3"], linewidth=2)
72
73
    # setting maker for the jump
74
    ax2.plot(
75
        x_left[-1],
76
        y_left[-1],
77
        marker="o",
78
        markersize=8,
79
        markerfacecolor=bg_color,
80
        markeredgecolor=palette["color4"],
81
        markeredgewidth=2,
82
    )
83
    ax2.plot(
84
        x_right[0],
85
        y_right[0],
86
        marker="o",
87
        markersize=8,
88
        markerfacecolor=palette["color4"],
89
        markeredgecolor=palette["color4"],
90
    )
91
92
    ax2.set_title("Mixed-Integer Problem", color=text_color, fontsize=14)
93
    ax2.set_xticks([])
94
    ax2.set_yticks([])
95
96
    plt.tight_layout()
97
98
    # save the plot
99
    if mode == "dark":
100
101
        plt.savefig("lin_vs_mixed_int_plot_dark.png")
102
    if mode == "light":
103
104
        plt.savefig("lin_vs_mixed_int_plot_light.png")
105
106
107
def draw_timeline(mode="dark", savefig_filename=None):
108
    """
109
    draws timeline for the multiperiod icon
110
    """
111
    if mode == "dark":
112
        palette = dark_palette
113
        bg_color = "#121212"
114
        text_color = "#FFFFFF"
115
    else:
116
        palette = light_palette
117
        bg_color = "#FFFFFF"
118
        text_color = "#000000"
119
120
    fig, ax = plt.subplots(figsize=(10, 3))
121
    fig.patch.set_facecolor(bg_color)
122
    ax.set_facecolor(bg_color)
123
124
    for spine in ax.spines.values():
125
        spine.set_visible(False)
126
    ax.tick_params(
127
        left=False, bottom=False, labelbottom=False, labelleft=False
128
    )
129
130
    years = list(range(2020, 2031))
131
132
    # draw line
133
    ax.plot(
134
        [years[0], years[-1]], [0, 0], color=palette["color1"], linewidth=2
135
    )
136
137
    # set markings for every year
138
    for i, year in enumerate(years):
139
        ax.plot(year, 0, marker="o", markersize=8, color=palette["color3"])
140
        ax.text(
141
            year,
142
            -0.3,
143
            str(year),
144
            ha="center",
145
            va="top",
146
            color=text_color,
147
            fontsize=10,
148
        )
149
        ax.text(
150
            year,
151
            0.3,
152
            f"Period {i+1}",
153
            ha="center",
154
            va="bottom",
155
            color=text_color,
156
            fontsize=10,
157
        )
158
159
    # Set title
160
    ax.text(
161
        (years[0] + years[-1]) / 2,
162
        0.8,
163
        "Multi-period Optimization",
164
        ha="center",
165
        va="bottom",
166
        color=text_color,
167
        fontsize=14,
168
        fontweight="bold",
169
    )
170
171
    ax.set_xlim(years[0] - 1, years[-1] + 1)
172
    ax.set_ylim(-1, 1)
173
174
    plt.tight_layout()
175
176
    # save png
177
    if mode == "dark":
178
179
        plt.savefig("timeline_dark.png")
180
    if mode == "light":
181
182
        plt.savefig("timeline_light.png")
183
184
185
def plot_dispatch_invest(csv_path, mode="dark"):
186
    """
187
    draws a demand timeseries next to an bar plot symbolizing the investment decisions
188
    """
189
190
    df = pd.read_csv(csv_path)
191
192
    if "Time" not in df.columns:
193
        df["Time"] = pd.date_range(
194
            start="2020-01-01", periods=len(df), freq="H"
195
        )
196
197
    if mode.lower() == "dark":
198
        palette = dark_palette
199
        bg_color = "#121212"
200
        text_color = "#FFFFFF"
201
    else:
202
        palette = light_palette
203
        bg_color = "#FFFFFF"
204
        text_color = "#000000"
205
206
    # create two subplots
207
    fig, axs = plt.subplots(1, 2, figsize=(16, 6))
208
    fig.patch.set_facecolor(bg_color)
209
210
    ax1 = axs[0]
211
    ax1.set_facecolor(bg_color)
212
    for spine in ax1.spines.values():
213
        spine.set_color(text_color)
214
    ax1.tick_params(colors=text_color, labelleft=False)
215
216
    # draw dispatch timeseries
217
    ax1.plot(
218
        df["Time"],
219
        df["demand_th"],
220
        marker="o",
221
        linestyle="-",
222
        color=palette["color1"],
223
        linewidth=2,
224
    )
225
    ax1.set_title("Dispatch Time Series (kW)", color=text_color, fontsize=14)
226
    ax1.set_xlabel("Time", color=text_color)
227
    ax1.set_ylabel("kW", color=text_color)
228
229
    avg_pv = df["pv"].mean() if "pv" in df.columns else 0
230
    avg_wind = df["wind"].mean() if "wind" in df.columns else 0
231
    avg_heatpump = 0.3
232
    avg_solarthermie = 0.09
233
234
    labels = ["PV", "Wind", "Heat Pump", "Solarthermie"]
235
    values = [avg_pv, avg_wind, avg_heatpump, avg_solarthermie]
236
237
    bar_colors = [
238
        palette["color3"],
239
        palette["color4"],
240
        palette["color2"],
241
        palette["color5"],
242
    ]
243
244
    ax2 = axs[1]
245
    ax2.set_facecolor(bg_color)
246
    for spine in ax2.spines.values():
247
        spine.set_color(text_color)
248
    ax2.tick_params(colors=text_color, labelleft=False)
249
250
    bars = ax2.bar(
251
        labels, values, color=bar_colors, edgecolor=text_color, linewidth=1.5
252
    )
253
254
    ax2.set_title("Investment Technology Sizes", color=text_color, fontsize=14)
255
    ax2.set_ylabel("Average Value", color=text_color, fontsize=14)
256
257
    fig.suptitle(
258
        "Dispatch vs. Invest-Optimization", color=text_color, fontsize=16
259
    )
260
261
    plt.tight_layout(rect=[0, 0, 1, 0.95])
262
263
    # save plots
264
    if mode == "dark":
265
266
        plt.savefig("plot_dispatch_invest_dark.png")
267
    if mode == "light":
268
269
        plt.savefig("plot_dispatch_invest_light.png")
270
271
272
# uncomment he needed funczion to redraw the icons
273
274
# draw_lin_vs_mixed_int('light')
275
# draw_lin_vs_mixed_int('dark')
276
277
# draw_timeline("dark")  # Speichert als "timeline_dark.png"
278
# draw_timeline("light")  # Speichert als "timeline_light.png"
279
280
file_name = os.path.realpath(
281
    os.path.join(
282
        __file__,
283
        "..",
284
        "..",
285
        "..",
286
        "..",
287
        "tests/test_outputlib/input_data.csv",
288
    )
289
)
290
plot_dispatch_invest(file_name, mode="light")
291
plot_dispatch_invest(file_name, mode="dark")
292