|
125 | 125 | "metadata": {},
|
126 | 126 | "source": [
|
127 | 127 | "After that, you can have a look at the computed values used to plot the\n",
|
128 |
| - "windrose with the ``ax._info`` dictionary : \n", |
| 128 | + "windrose with the `ax._info` dictionary :\n", |
129 | 129 | "\n",
|
130 |
| - "- ``ax._info['bins']`` :\n", |
| 130 | + "- `ax._info['bins']` :\n", |
131 | 131 | " list of bins (limits) used for wind speeds. If not set in the call, bins\n",
|
132 |
| - " will be set to 6 parts between wind speed min and max. \n", |
133 |
| - "- ``ax._info['dir']`` : list of directions \"boundaries\" used to compute the\n", |
| 132 | + " will be set to 6 parts between wind speed min and max.\n", |
| 133 | + "- `ax._info['dir']` : list of directions \"boundaries\" used to compute the\n", |
134 | 134 | " distribution by wind direction sector. This can be set by the nsector\n",
|
135 |
| - " parameter (see below). \n", |
136 |
| - "- ``ax._info['table']`` : the resulting table of\n", |
| 135 | + " parameter (see below).\n", |
| 136 | + "- `ax._info['table']` : the resulting table of\n", |
137 | 137 | " the computation. It's a 2D histogram, where each line represents a wind\n",
|
138 | 138 | " speed class, and each column represents a wind direction class.\n",
|
139 | 139 | "\n",
|
|
171 | 171 | "\n",
|
172 | 172 | "plt.bar(np.arange(16), wd_freq, align=\"center\")\n",
|
173 | 173 | "xlabels = (\n",
|
174 |
| - " \"N\", \"\",\n", |
175 |
| - " \"N-E\", \"\",\n", |
176 |
| - " \"E\", \"\",\n", |
177 |
| - " \"S-E\", \"\",\n", |
178 |
| - " \"S\", \"\",\n", |
179 |
| - " \"S-O\", \"\",\n", |
180 |
| - " \"O\", \"\",\n", |
181 |
| - " \"N-O\", \"\",\n", |
| 174 | + " \"N\",\n", |
| 175 | + " \"\",\n", |
| 176 | + " \"N-E\",\n", |
| 177 | + " \"\",\n", |
| 178 | + " \"E\",\n", |
| 179 | + " \"\",\n", |
| 180 | + " \"S-E\",\n", |
| 181 | + " \"\",\n", |
| 182 | + " \"S\",\n", |
| 183 | + " \"\",\n", |
| 184 | + " \"S-O\",\n", |
| 185 | + " \"\",\n", |
| 186 | + " \"O\",\n", |
| 187 | + " \"\",\n", |
| 188 | + " \"N-O\",\n", |
| 189 | + " \"\",\n", |
182 | 190 | ")\n",
|
183 | 191 | "xticks = np.arange(16)\n",
|
184 | 192 | "plt.gca().set_xticks(xticks)\n",
|
|
192 | 200 | "In addition of all the standard pyplot parameters, you can pass special\n",
|
193 | 201 | "parameters to control the windrose production. For the stacked histogram\n",
|
194 | 202 | "windrose, calling help(ax.bar) will give :\n",
|
195 |
| - "``bar(self, direction, var, **kwargs)`` method of\n", |
196 |
| - "``windrose.WindroseAxes`` instance Plot a windrose in bar mode. For each\n", |
| 203 | + "`bar(self, direction, var, **kwargs)` method of\n", |
| 204 | + "`windrose.WindroseAxes` instance Plot a windrose in bar mode. For each\n", |
197 | 205 | "var bins and for each sector, a colored bar will be draw on the axes.\n",
|
198 | 206 | "\n",
|
199 | 207 | "Mandatory:\n",
|
200 | 208 | "\n",
|
201 |
| - "- ``direction`` : 1D array - directions the wind blows from, North centred\n", |
202 |
| - "- ``var`` : 1D array - values of the variable to compute. Typically the wind speeds\n", |
| 209 | + "- `direction` : 1D array - directions the wind blows from, North centred\n", |
| 210 | + "- `var` : 1D array - values of the variable to compute. Typically the wind speeds\n", |
203 | 211 | "\n",
|
204 |
| - "Optional: \n", |
| 212 | + "Optional:\n", |
205 | 213 | "\n",
|
206 |
| - "- ``nsector`` : integer - number of sectors used to compute\n", |
| 214 | + "- `nsector` : integer - number of sectors used to compute\n", |
207 | 215 | " the windrose table. If not set, nsectors=16, then each sector will be\n",
|
208 | 216 | " 360/16=22.5°, and the resulting computed table will be aligned with the\n",
|
209 | 217 | " cardinals points.\n",
|
210 |
| - "- ``bins`` : 1D array or integer - number of bins, or a\n", |
| 218 | + "- `bins` : 1D array or integer - number of bins, or a\n", |
211 | 219 | " sequence of bins variable. If not set, bins=6 between min(var) and\n",
|
212 | 220 | " max(var).\n",
|
213 |
| - "- ``blowto`` : bool. If True, the windrose will be pi rotated,\n", |
214 |
| - " to show where the wind blow to (useful for pollutant rose). \n", |
215 |
| - "- ``colors`` : string or tuple - one string color (``'k'`` or\n", |
216 |
| - " ``'black'``), in this case all bins will be plotted in this color; a\n", |
| 221 | + "- `blowto` : bool. If True, the windrose will be pi rotated,\n", |
| 222 | + " to show where the wind blow to (useful for pollutant rose).\n", |
| 223 | + "- `colors` : string or tuple - one string color (`'k'` or\n", |
| 224 | + " `'black'`), in this case all bins will be plotted in this color; a\n", |
217 | 225 | " tuple of matplotlib color args (string, float, rgb, etc), different\n",
|
218 |
| - " levels will be plotted in different colors in the order specified. \n", |
219 |
| - "- ``cmap`` : a cm Colormap instance from ``matplotlib.cm``. - if\n", |
220 |
| - " ``cmap == None`` and ``colors == None``, a default Colormap is used. \n", |
221 |
| - "- ``edgecolor`` : string - The string color each edge bar will be plotted.\n", |
222 |
| - " Default : no edgecolor \n", |
223 |
| - "- ``opening`` : float - between 0.0 and 1.0, to\n", |
224 |
| - " control the space between each sector (1.0 for no space) \n", |
225 |
| - "- ``mean_values`` : Bool - specify wind speed statistics with\n", |
| 226 | + " levels will be plotted in different colors in the order specified.\n", |
| 227 | + "- `cmap` : a cm Colormap instance from `matplotlib.cm`. - if\n", |
| 228 | + " `cmap == None` and `colors == None`, a default Colormap is used.\n", |
| 229 | + "- `edgecolor` : string - The string color each edge bar will be plotted.\n", |
| 230 | + " Default : no edgecolor\n", |
| 231 | + "- `opening` : float - between 0.0 and 1.0, to\n", |
| 232 | + " control the space between each sector (1.0 for no space)\n", |
| 233 | + "- `mean_values` : Bool - specify wind speed statistics with\n", |
226 | 234 | " direction=specific mean wind speeds. If this flag is specified, var is\n",
|
227 | 235 | " expected to be an array of mean wind speeds corresponding to each entry\n",
|
228 |
| - " in ``direction``. These are used to generate a distribution of wind\n", |
229 |
| - " speeds assuming the distribution is Weibull with shape factor = 2. \n", |
230 |
| - "- ``weibull_factors`` : Bool - specify wind speed statistics with\n", |
| 236 | + " in `direction`. These are used to generate a distribution of wind\n", |
| 237 | + " speeds assuming the distribution is Weibull with shape factor = 2.\n", |
| 238 | + "- `weibull_factors` : Bool - specify wind speed statistics with\n", |
231 | 239 | " direction=specific weibull scale and shape factors. If this flag is\n",
|
232 |
| - " specified, var is expected to be of the form [[7,2], ...., [7.5,1.9]]\n", |
233 |
| - " where var[i][0] is the weibull scale factor and var[i][1] is the shape\n", |
| 240 | + " specified, var is expected to be of the form \\[\\[7,2\\], ...., \\[7.5,1.9\\]\\]\n", |
| 241 | + " where var\\[i\\]\\[0\\] is the weibull scale factor and var\\[i\\]\\[1\\] is the shape\n", |
234 | 242 | " factor"
|
235 | 243 | ]
|
236 | 244 | },
|
|
268 | 276 | "metadata": {},
|
269 | 277 | "outputs": [],
|
270 | 278 | "source": [
|
271 |
| - "print(params)" |
| 279 | + "print(f\"{params=}\")" |
272 | 280 | ]
|
273 | 281 | },
|
274 | 282 | {
|
|
371 | 379 | "metadata": {},
|
372 | 380 | "outputs": [],
|
373 | 381 | "source": [
|
374 |
| - "from windrose import WindroseAxes, plot_windrose\n", |
375 |
| - "import seaborn as sns\n", |
376 |
| - "from matplotlib import pyplot as plt\n", |
377 | 382 | "import numpy as np\n",
|
378 | 383 | "import pandas as pd\n",
|
| 384 | + "import seaborn as sns\n", |
| 385 | + "from matplotlib import pyplot as plt\n", |
379 | 386 | "\n",
|
380 |
| - "wind_data = pd.DataFrame({\n", |
381 |
| - " 'ws': np.random.random(1200) * 6,\n", |
382 |
| - " 'wd': np.random.random(1200) * 360,\n", |
383 |
| - " 'month': np.repeat(range(1, 13), 100),\n", |
384 |
| - "})\n", |
| 387 | + "from windrose import WindroseAxes, plot_windrose\n", |
| 388 | + "\n", |
| 389 | + "wind_data = pd.DataFrame(\n", |
| 390 | + " {\n", |
| 391 | + " \"ws\": np.random.random(1200) * 6,\n", |
| 392 | + " \"wd\": np.random.random(1200) * 360,\n", |
| 393 | + " \"month\": np.repeat(range(1, 13), 100),\n", |
| 394 | + " }\n", |
| 395 | + ")\n", |
385 | 396 | "\n",
|
386 | 397 | "\n",
|
387 | 398 | "def plot_windrose_subplots(data, *, direction, var, color=None, **kwargs):\n",
|
|
390 | 401 | " ax = WindroseAxes.from_ax(ax=ax)\n",
|
391 | 402 | " plot_windrose(direction_or_df=data[direction], var=data[var], ax=ax, **kwargs)\n",
|
392 | 403 | "\n",
|
| 404 | + "\n", |
393 | 405 | "# this creates the raw subplot structure with a subplot per value in month.\n",
|
394 | 406 | "g = sns.FacetGrid(\n",
|
395 | 407 | " data=wind_data,\n",
|
396 | 408 | " # the column name for each level a subplot should be created\n",
|
397 |
| - " col='month',\n", |
| 409 | + " col=\"month\",\n", |
398 | 410 | " # place a maximum of 3 plots per row\n",
|
399 | 411 | " col_wrap=3,\n",
|
400 |
| - " subplot_kws={'projection': 'windrose'},\n", |
| 412 | + " subplot_kws={\"projection\": \"windrose\"},\n", |
401 | 413 | " sharex=False,\n",
|
402 | 414 | " sharey=False,\n",
|
403 | 415 | " despine=False,\n",
|
404 |
| - " height=3.5\n", |
| 416 | + " height=3.5,\n", |
405 | 417 | ")\n",
|
406 | 418 | "\n",
|
407 | 419 | "g.map_dataframe(\n",
|
408 | 420 | " plot_windrose_subplots,\n",
|
409 |
| - " direction='wd',\n", |
410 |
| - " var='ws',\n", |
| 421 | + " direction=\"wd\",\n", |
| 422 | + " var=\"ws\",\n", |
411 | 423 | " normed=True,\n",
|
412 | 424 | " # manually set bins, so they match for each subplot\n",
|
413 | 425 | " bins=(0.1, 1, 2, 3, 4, 5),\n",
|
414 | 426 | " calm_limit=0.1,\n",
|
415 |
| - " kind='bar'\n", |
| 427 | + " kind=\"bar\",\n", |
416 | 428 | ")\n",
|
417 | 429 | "\n",
|
418 | 430 | "# make the subplots easier to compare, by having the same y-axis range\n",
|
419 | 431 | "y_ticks = range(0, 17, 4)\n",
|
420 | 432 | "for ax in g.axes:\n",
|
421 |
| - " ax.set_legend(title='$m \\cdot s^{-1}$', bbox_to_anchor=(1.15, -.1), loc='lower right')\n", |
| 433 | + " ax.set_legend(\n", |
| 434 | + " title=\"$m \\cdot s^{-1}$\", bbox_to_anchor=(1.15, -0.1), loc=\"lower right\"\n", |
| 435 | + " )\n", |
422 | 436 | " ax.set_rgrids(y_ticks, y_ticks)\n",
|
423 | 437 | "\n",
|
424 | 438 | "# adjust the spacing between the subplots to have sufficient space between plots\n",
|
425 |
| - "plt.subplots_adjust(wspace=-.2)" |
| 439 | + "plt.subplots_adjust(wspace=-0.2)" |
426 | 440 | ]
|
427 | 441 | },
|
428 | 442 | {
|
|
437 | 451 | "metadata": {},
|
438 | 452 | "source": [
|
439 | 453 | "Instead of using object oriented approach like previously shown, some\n",
|
440 |
| - "\"shortcut\" functions have been defined: ``wrbox``, ``wrbar``,\n", |
441 |
| - "``wrcontour``, ``wrcontourf``, ``wrpdf``. See [unit tests](https://github.com/python-windrose/windrose/blob/master/tests/test_windrose.py)." |
| 454 | + "\"shortcut\" functions have been defined: `wrbox`, `wrbar`,\n", |
| 455 | + "`wrcontour`, `wrcontourf`, `wrpdf`. See [unit tests](https://github.com/python-windrose/windrose/blob/master/tests/test_windrose.py)." |
442 | 456 | ]
|
443 | 457 | },
|
444 | 458 | {
|
|
453 | 467 | "metadata": {},
|
454 | 468 | "source": [
|
455 | 469 | "windrose not only supports Numpy arrays. It also supports also Pandas\n",
|
456 |
| - "DataFrame. ``plot_windrose`` function provides most of plotting features\n", |
| 470 | + "DataFrame. `plot_windrose` function provides most of plotting features\n", |
457 | 471 | "previously shown."
|
458 | 472 | ]
|
459 | 473 | },
|
|
465 | 479 | "source": [
|
466 | 480 | "import pandas as pd\n",
|
467 | 481 | "\n",
|
468 |
| - "from windrose import plot_windrose\n", |
469 |
| - "\n", |
470 | 482 | "N = 500\n",
|
471 | 483 | "ws = np.random.random(N) * 6\n",
|
472 | 484 | "wd = np.random.random(N) * 360\n",
|
|
480 | 492 | "source": [
|
481 | 493 | "Mandatory:\n",
|
482 | 494 | "\n",
|
483 |
| - "- ``df``: Pandas DataFrame with ``DateTimeIndex`` as index\n", |
484 |
| - " and at least 2 columns (``'speed'`` and ``'direction'``).\n", |
| 495 | + "- `df`: Pandas DataFrame with `DateTimeIndex` as index\n", |
| 496 | + " and at least 2 columns (`'speed'` and `'direction'`).\n", |
485 | 497 | "\n",
|
486 |
| - "Optional: \n", |
| 498 | + "Optional:\n", |
487 | 499 | "\n",
|
488 |
| - "- ``kind`` : kind of plot (might be either, ``'contour'``, ``'contourf'``, ``'bar'``, ``'box'``, ``'pdf'``)\n", |
489 |
| - "- ``var_name`` : name of var column name ; default value is ``VAR_DEFAULT='speed'``\n", |
490 |
| - "- ``direction_name`` : name of direction column name ; default value is\n", |
491 |
| - " ``DIR_DEFAULT='direction'``\n", |
492 |
| - "- ``clean_flag`` : cleanup data flag (remove\n", |
493 |
| - " data points with ``NaN``, ``var=0``) before plotting ; default value is\n", |
494 |
| - " ``True``." |
| 500 | + "- `kind` : kind of plot (might be either, `'contour'`, `'contourf'`, `'bar'`, `'box'`, `'pdf'`)\n", |
| 501 | + "- `var_name` : name of var column name ; default value is `VAR_DEFAULT='speed'`\n", |
| 502 | + "- `direction_name` : name of direction column name ; default value is\n", |
| 503 | + " `DIR_DEFAULT='direction'`\n", |
| 504 | + "- `clean_flag` : cleanup data flag (remove\n", |
| 505 | + " data points with `NaN`, `var=0`) before plotting ; default value is\n", |
| 506 | + " `True`." |
495 | 507 | ]
|
496 | 508 | },
|
497 | 509 | {
|
|
500 | 512 | "source": [
|
501 | 513 | "## Video export\n",
|
502 | 514 | "\n",
|
503 |
| - "\n", |
504 | 515 | "A video of plots can be exported. A playlist of videos is [available here](https://www.youtube.com/playlist?list=PLE9hIvV5BUzsQ4EPBDnJucgmmZ85D_b-W), see:\n",
|
505 | 516 | "\n",
|
506 | 517 | "[](https://www.youtube.com/watch?v=0u2RxtGgEFo)\n",
|
|
539 | 550 | "name": "python",
|
540 | 551 | "nbconvert_exporter": "python",
|
541 | 552 | "pygments_lexer": "ipython3",
|
542 |
| - "version": "3.11.3" |
| 553 | + "version": "3.11.4" |
543 | 554 | }
|
544 | 555 | },
|
545 | 556 | "nbformat": 4,
|
|
0 commit comments