-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcase_reeves_morley_friedel_2011.html
884 lines (856 loc) · 132 KB
/
case_reeves_morley_friedel_2011.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
<!DOCTYPE html>
<html lang="en" data-content_root="./">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.18.1: http://docutils.sourceforge.net/" />
<title>Paulikas and Blake revisited (Reeves et al. 2011) — SpacePy v0.7.0 Manual</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=b76e3c8a" />
<link rel="stylesheet" type="text/css" href="_static/sphinxdoc.css?v=92e3d466" />
<link rel="stylesheet" type="text/css" href="_static/graphviz.css?v=fd3f3429" />
<link rel="stylesheet" type="text/css" href="_static/plot_directive.css" />
<script src="_static/documentation_options.js?v=fe7df9b0"></script>
<script src="_static/doctools.js?v=9a2dae69"></script>
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
<script type="text/javascript" src="_static/copybutton.js"></script>
<link rel="icon" href="_static/spacepy_favicon.ico"/>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Publication List" href="publications.html" />
<link rel="prev" title="SpacePy Case Studies" href="case_studies.html" />
</head><body>
<div style="background-color: white; text-align: left; padding: 10px 10px 15px 15px">
<a href="index.html"><img src="_static/spacepy_logo.jpg" border="0" alt="spacepy_logo"/></a>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="publications.html" title="Publication List"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="case_studies.html" title="SpacePy Case Studies"
accesskey="P">previous</a> |</li>
<li><a href="https://spacepy.github.io/"">homepage</a>| </li>
<li><a href="https://github.com/spacepy/spacepy">development</a>| </li>
<li><a href="search.html">search</a>| </li>
<li><a href="index.html">documentation </a> »</li>
<li class="nav-item nav-item-1"><a href="case_studies.html" accesskey="U">SpacePy Case Studies</a> »</li>
<li class="nav-item nav-item-this"><a href="">Paulikas and Blake revisited (Reeves et al. 2011)</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="paulikas-and-blake-revisited-reeves-et-al-2011">
<h1>Paulikas and Blake revisited (Reeves et al. 2011)<a class="headerlink" href="#paulikas-and-blake-revisited-reeves-et-al-2011" title="Link to this heading">¶</a></h1>
<p>This case study reproduces the figures of Reeves et al. (2011),
“On the relationship between relativistic electron flux and solar wind
velocity: Paulikas and Blake revisited”
(<a class="reference external" href="http://dx.doi.org/10.1029/2010JA015735">doi:10.1029/2010JA015735</a>).</p>
<section id="setup">
<h2>Setup<a class="headerlink" href="#setup" title="Link to this heading">¶</a></h2>
<p>Create a directory to hold files for this case study. Within this
directory, create subdirectories <code class="docutils literal notranslate"><span class="pre">code</span></code>, <code class="docutils literal notranslate"><span class="pre">data</span></code>, and
<code class="docutils literal notranslate"><span class="pre">plots</span></code>. (Using version control on the code directory is
recommended; the SpacePy team uses <a class="reference external" href="http://git-scm.com/documentation">git</a>.)</p>
</section>
<section id="obtaining-energetic-particle-data">
<h2>Obtaining energetic particle data<a class="headerlink" href="#obtaining-energetic-particle-data" title="Link to this heading">¶</a></h2>
<p>We require the 1.8-3.5 MeV electron flux from the LANL-GEO ESP
detector, available in the paper’s auxiliary material (scroll down to “Supporting information” on the <a class="reference external" href="http://dx.doi.org/10.1029/2010JA015735">paper’s page</a>. The
ESP data are in Data Set S1. Save this file to the <code class="docutils literal notranslate"><span class="pre">data</span></code> directory;
the filename is assumed to be <code class="docutils literal notranslate"><span class="pre">jgra20797-sup-0003-ds01.txt</span></code>.</p>
<p>The data file was corrupted on upload to AGU, and the code to fix it
is non-trivial, so this is a good chance to learn how to run someone
else’s code. (<a class="reference internal" href="#appendix"><span class="std std-ref">Appendix: Fixing the ESP data file</span></a> has step-by-step information on each
portion of this process.) Copy all of the following and paste it into
a file called <code class="docutils literal notranslate"><span class="pre">fix_esp_data.py</span></code> in the <code class="docutils literal notranslate"><span class="pre">code</span></code> directory.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">os.path</span>
<span class="n">datadir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">'..'</span><span class="p">,</span> <span class="s1">'data'</span><span class="p">)</span>
<span class="n">in_name</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">datadir</span><span class="p">,</span> <span class="s1">'jgra20797-sup-0003-ds01.txt'</span><span class="p">)</span>
<span class="n">out_name</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">datadir</span><span class="p">,</span> <span class="s1">'jgra20797-sup-0003-ds01_FIXED.txt'</span><span class="p">)</span>
<span class="n">infile</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">in_name</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">)</span>
<span class="n">outfile</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">out_name</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">infile</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="n">infile</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'</span><span class="se">\r</span><span class="s1">'</span><span class="p">,</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'</span><span class="se">\n\n</span><span class="s1">'</span><span class="p">,</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">15</span><span class="p">):</span>
<span class="n">outfile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
<span class="n">oldline</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
<span class="k">if</span> <span class="n">line</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="mi">2</span><span class="p">]</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">'19'</span><span class="p">,</span> <span class="s1">'20'</span><span class="p">,</span> <span class="s1">'2'</span><span class="p">]:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">oldline</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">outfile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">oldline</span> <span class="o">+</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
<span class="n">oldline</span> <span class="o">=</span> <span class="n">line</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">oldline</span> <span class="o">+=</span> <span class="n">line</span>
<span class="n">outfile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">oldline</span> <span class="o">+</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
<span class="n">outfile</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
</div>
<p>Now this script can be run with <code class="docutils literal notranslate"><span class="pre">python</span> <span class="pre">fix_esp_data.py</span></code>. It should
create a file called <code class="docutils literal notranslate"><span class="pre">jgra20797-sup-0003-ds01_FIXED.txt</span></code> in the <code class="docutils literal notranslate"><span class="pre">data</span></code>
directory.</p>
<p>File fixed, we can load and begin examining the data. Change to the
<code class="docutils literal notranslate"><span class="pre">code</span></code> directory and start your Python interpreter. (<a class="reference external" href="http://ipython.org/">IPython</a> is recommended, but not required.)</p>
<p>In the following examples, do not type the leading <code class="docutils literal notranslate"><span class="pre">>>></span></code>; this is
the Python interpreter prompt. IPython has a different prompt that
looks like <code class="docutils literal notranslate"><span class="pre">In</span> <span class="pre">[1]</span></code>.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">os.path</span>
<span class="gp">>>> </span><span class="n">datadir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">'..'</span><span class="p">,</span> <span class="s1">'data'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="n">datadir</span><span class="p">)</span>
<span class="go">../data</span>
</pre></div>
</div>
<p>The first line imports the <a class="reference external" href="https://docs.python.org/3/library/os.path.html#module-os.path" title="(in Python v3.13)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">os.path</span></code></a> module from the Python
standard library. Python has a huge <a class="reference external" href="http://docs.python.org/library/index.html">standard library</a>. To keep this code
organized, it is divided into many modules, and a module must be
imported before it can be used. (The <a class="reference external" href="http://www.doughellmann.com/PyMOTW/">Python module of the week</a> is a great way to explore the
standard library.)</p>
<p>The second line makes a variable, <code class="docutils literal notranslate"><span class="pre">datadir</span></code>, which will contain the
path of the data directory. The <a class="reference external" href="https://docs.python.org/3/library/os.path.html#os.path.join" title="(in Python v3.13)"><code class="xref py py-func docutils literal notranslate"><span class="pre">os.path.join()</span></code></a> function
provides a portable way of “gluing” together directories in a path,
and will use backslashes on Windows and forward slashes on Unix. The
third line then prints out the value of this variable for
confirmation; note this is a Unix system.</p>
<p>Note that string constants in Python can use single or double quotes;
we could just as well have written:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">datadir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s2">".."</span><span class="p">,</span> <span class="s2">"data"</span><span class="p">)</span>
</pre></div>
</div>
<p>or even:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">datadir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">'..'</span><span class="p">,</span> <span class="s2">"data"</span><span class="p">)</span>
</pre></div>
</div>
<p>The full path can also be used (and this is a better case for using a
variable.) For example, I am preparing this example in a directory
<code class="docutils literal notranslate"><span class="pre">reeves_morley_friedel_2011</span></code> in my home directory, so I could use:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">datadir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">'home'</span><span class="p">,</span> <span class="s1">'jniehof'</span><span class="p">,</span> <span class="s1">'reeves_morley_friedel_2011'</span><span class="p">,</span>
<span class="gp">... </span> <span class="s1">'data'</span><span class="p">)</span>
</pre></div>
</div>
<p>This very long line can be typed across two lines in Python, and
because the line break happens within parentheses, a line continuation
character is not required.</p>
<p>Returning to reading the ESP data file:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">fname</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">datadir</span><span class="p">,</span> <span class="s1">'jgra20797-sup-0003-ds01_FIXED.txt'</span><span class="p">)</span>
</pre></div>
</div>
<p>creates a variable holding the full path to the fixed file.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">numpy</span>
</pre></div>
</div>
<p>The import statement imports any installed <a class="reference external" href="http://docs.python.org/tutorial/modules.html">module</a>, just as if it were in the standard library. Here we import the very useful <a class="reference external" href="https://numpy.org/doc/stable/reference/index.html#module-numpy" title="(in NumPy v2.1)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">numpy</span></code></a> module, which is a prerequisite for SpacePy and useful in its own right.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">esp_fluxes</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">loadtxt</span><span class="p">(</span><span class="n">fname</span><span class="p">,</span> <span class="n">skiprows</span><span class="o">=</span><span class="mi">14</span><span class="p">,</span> <span class="n">usecols</span><span class="o">=</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<p><a class="reference external" href="https://numpy.org/doc/stable/reference/generated/numpy.loadtxt.html#numpy.loadtxt" title="(in NumPy v2.1)"><code class="xref py py-func docutils literal notranslate"><span class="pre">loadtxt()</span></code></a> makes it easy to load data from a file into a
numpy <a class="reference external" href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray" title="(in NumPy v2.1)"><code class="xref py py-class docutils literal notranslate"><span class="pre">ndarray</span></code></a>, a very useful data
container. <code class="docutils literal notranslate"><span class="pre">skiprows</span></code> skips the header information, and specifying
only column 1 (first column is column 0) with <code class="docutils literal notranslate"><span class="pre">usecols</span></code> will only
load the fluxes for 1.8-3.5MeV. We only load the fluxes at this point
because they can be represented as floats, which numpy arrays store
very efficiently.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">datetime</span>
</pre></div>
</div>
<p>The <a class="reference external" href="https://docs.python.org/3/library/datetime.html#module-datetime" title="(in Python v3.13)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">datetime</span></code></a> module provides Python objects which can manipulate dates and times and have some understanding of the meanings of dates, making for easy comparisons between dates, date arithmetic, and other useful features.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">convert</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="s1">'%Y-%m-</span><span class="si">%d</span><span class="s1">'</span><span class="p">)</span>
</pre></div>
</div>
<p>This line sets up a converter to be used later. <a class="reference external" href="https://docs.python.org/3/library/datetime.html#datetime.datetime.strptime" title="(in Python v3.13)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">strptime()</span></code></a> creates a <a class="reference external" href="https://docs.python.org/3/library/datetime.html#datetime.datetime" title="(in Python v3.13)"><code class="xref py py-class docutils literal notranslate"><span class="pre">datetime</span></code></a> from a string, given a format definition (here specified as year-month-day). So:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="s1">'2010-01-02'</span><span class="p">,</span> <span class="s1">'%Y-%m-</span><span class="si">%d</span><span class="s1">'</span><span class="p">))</span>
<span class="go">2010-01-02 00:00:00</span>
</pre></div>
</div>
<p><a class="reference external" href="http://docs.python.org/tutorial/controlflow.html#lambda-forms">lambda</a> is a
simple shortcut for a one-liner function; wherever <code class="docutils literal notranslate"><span class="pre">convert(x)</span></code> is
used after the definition, it functions like
<code class="docutils literal notranslate"><span class="pre">datetime.datetime.strptime(x,</span> <span class="pre">'%Y-%m-%d')</span></code>. This makes it easier to
parse a date string without specifying the format all the time:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="n">convert</span><span class="p">(</span><span class="s1">'2010-01-02'</span><span class="p">))</span>
</pre></div>
</div>
<p>This converter can be used with <a class="reference external" href="https://numpy.org/doc/stable/reference/generated/numpy.loadtxt.html#numpy.loadtxt" title="(in NumPy v2.1)"><code class="xref py py-func docutils literal notranslate"><span class="pre">loadtxt()</span></code></a>:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">esp_times</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">loadtxt</span><span class="p">(</span><span class="n">fname</span><span class="p">,</span> <span class="n">skiprows</span><span class="o">=</span><span class="mi">14</span><span class="p">,</span> <span class="n">usecols</span><span class="o">=</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
<span class="gp">... </span> <span class="n">converters</span><span class="o">=</span><span class="p">{</span><span class="mi">0</span><span class="p">:</span> <span class="n">convert</span><span class="p">},</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">object</span><span class="p">)</span>
</pre></div>
</div>
<p>The <code class="docutils literal notranslate"><span class="pre">converters</span></code> option takes a Python <a class="reference external" href="http://docs.python.org/tutorial/datastructures.html#dictionaries">dictionary</a>. The
default <a class="reference external" href="http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html">dtype</a> is
float, which cannot store datetimes; using <code class="docutils literal notranslate"><span class="pre">numpy.object</span></code>
allows storage of any Python object.</p>
<p>Since it would be useful to be able to load the data without typing so
many lines, create a file called <code class="docutils literal notranslate"><span class="pre">common.py</span></code> in the <code class="docutils literal notranslate"><span class="pre">code</span></code>
directory with the following contents:</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">datetime</span>
<span class="kn">import</span> <span class="nn">os.path</span>
<span class="kn">import</span> <span class="nn">numpy</span>
<span class="n">datadir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">'..'</span><span class="p">,</span> <span class="s1">'data'</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">load_esp</span><span class="p">():</span>
<span class="n">fname</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">datadir</span><span class="p">,</span> <span class="s1">'jgra20797-sup-0003-ds01_FIXED.txt'</span><span class="p">)</span>
<span class="n">esp_fluxes</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">loadtxt</span><span class="p">(</span><span class="n">fname</span><span class="p">,</span> <span class="n">skiprows</span><span class="o">=</span><span class="mi">14</span><span class="p">,</span> <span class="n">usecols</span><span class="o">=</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
<span class="n">convert</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="s1">'%Y-%m-</span><span class="si">%d</span><span class="s1">'</span><span class="p">)</span>
<span class="n">esp_times</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">loadtxt</span><span class="p">(</span><span class="n">fname</span><span class="p">,</span> <span class="n">skiprows</span><span class="o">=</span><span class="mi">14</span><span class="p">,</span> <span class="n">usecols</span><span class="o">=</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
<span class="n">converters</span><span class="o">=</span><span class="p">{</span><span class="mi">0</span><span class="p">:</span> <span class="n">convert</span><span class="p">},</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">object</span><span class="p">)</span>
<span class="k">return</span> <span class="p">(</span><span class="n">esp_times</span><span class="p">,</span> <span class="n">esp_fluxes</span><span class="p">)</span>
</pre></div>
</div>
<p>All needed imports are at the top of the file, with one blank line
between standard library imports and other imports and two blank lines
after them. <code class="docutils literal notranslate"><span class="pre">datadir</span></code> is defined as a global variable, outside of
the function (but notice that it is available to the <code class="docutils literal notranslate"><span class="pre">load_esp</span></code>
function.)</p>
<p>The rest of the file defines a <a class="reference external" href="http://docs.python.org/tutorial/controlflow.html#defining-functions">function</a>
which returns the dates and fluxes in a <a class="reference external" href="http://docs.python.org/tutorial/datastructures.html#tuples-and-sequences">tuple</a>. The
next section shows how to use this function.</p>
</section>
<section id="solar-wind-data-and-averaging">
<h2>Solar Wind data and averaging<a class="headerlink" href="#solar-wind-data-and-averaging" title="Link to this heading">¶</a></h2>
<p>The top panel of figure 1 shows the ESP fluxes overplotted with the
solar wind velocity. Fortunately, the <a class="reference internal" href="autosummary/spacepy.omni.html#module-spacepy.omni" title="spacepy.omni"><code class="xref py py-mod docutils literal notranslate"><span class="pre">omni</span></code></a> module of
SpacePy provides an interface to the hourly solar wind dataset,
OMNI. <a class="reference internal" href="autosummary/spacepy.omni.html#spacepy.omni.get_omni" title="spacepy.omni.get_omni"><code class="xref py py-func docutils literal notranslate"><span class="pre">get_omni()</span></code></a> returns data for a particular
set of times. In this case, we want hourly data, covering 1989 through
2010 (we’ll cut it down to size later). <a class="reference internal" href="autosummary/spacepy.time.html#spacepy.time.tickrange" title="spacepy.time.tickrange"><code class="xref py py-func docutils literal notranslate"><span class="pre">tickrange()</span></code></a>
allows us to specify a start time, stop time, and time step.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">spacepy.omni</span>
<span class="gp">>>> </span><span class="kn">import</span> <span class="nn">spacepy.time</span>
<span class="gp">>>> </span><span class="n">times</span> <span class="o">=</span> <span class="n">spacepy</span><span class="o">.</span><span class="n">time</span><span class="o">.</span><span class="n">tickrange</span><span class="p">(</span><span class="s1">'1989-01-01'</span><span class="p">,</span> <span class="s1">'2011-01-01'</span><span class="p">,</span>
<span class="gp">... </span> <span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">(</span><span class="n">hours</span><span class="o">=</span><span class="mi">1</span><span class="p">))</span>
<span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">spacepy</span><span class="o">.</span><span class="n">omni</span><span class="o">.</span><span class="n">get_omni</span><span class="p">(</span><span class="n">times</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">vsw</span> <span class="o">=</span> <span class="n">d</span><span class="p">[</span><span class="s1">'velo'</span><span class="p">]</span>
<span class="gp">>>> </span><span class="n">vsw_times</span> <span class="o">=</span> <span class="n">d</span><span class="p">[</span><span class="s1">'UTC'</span><span class="p">]</span>
</pre></div>
</div>
<p>We’ll also load the esp data:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">common</span>
<span class="gp">>>> </span><span class="n">esp_times</span><span class="p">,</span> <span class="n">esp_flux</span> <span class="o">=</span> <span class="n">common</span><span class="o">.</span><span class="n">load_esp</span><span class="p">()</span>
</pre></div>
</div>
<p>Even though we have not installed <code class="docutils literal notranslate"><span class="pre">common.py</span></code>, the <code class="docutils literal notranslate"><span class="pre">import</span></code>
statement finds it because it is in the current directory.</p>
<p><code class="docutils literal notranslate"><span class="pre">load_esp</span></code> returns a <a class="reference external" href="http://docs.python.org/tutorial/datastructures.html#tuples-and-sequences">tuple</a>,
which can be <em>unpacked</em> into separate variables.</p>
<p>Now we need to produce 27-day running averages of both the flux and
the solar wind speed. Fortunately there are no gaps in the time
series:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">numpy</span>
<span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">diff</span><span class="p">(</span><span class="n">vsw_times</span><span class="p">)</span>
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">min</span><span class="p">())</span>
<span class="go">1:00:00</span>
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">max</span><span class="p">())</span>
<span class="go">1:00:00</span>
<span class="gp">>>> </span><span class="n">d</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">diff</span><span class="p">(</span><span class="n">esp_times</span><span class="p">)</span>
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">min</span><span class="p">())</span>
<span class="go">1 day, 0:00:00</span>
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">max</span><span class="p">())</span>
<span class="go">1 day, 0:00:00</span>
</pre></div>
</div>
<p><a class="reference external" href="https://numpy.org/doc/stable/reference/generated/numpy.diff.html#numpy.diff" title="(in NumPy v2.1)"><code class="xref py py-func docutils literal notranslate"><span class="pre">numpy.diff()</span></code></a> returns the difference between every element of an
array and the previous element. <a class="reference external" href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.min.html#numpy.ndarray.min" title="(in NumPy v2.1)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">min()</span></code></a> and
<a class="reference external" href="https://numpy.org/doc/stable/reference/generated/numpy.ndarray.max.html#numpy.ndarray.max" title="(in NumPy v2.1)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">max()</span></code></a> do exactly what they sound like. So this
code confirms that every time in the vsw data is on a continuous one
hour cadence, and the ESP data is on a continuous one day cadence.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">scipy.stats</span>
<span class="gp">>>> </span><span class="n">esp_flux_av</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">empty</span><span class="p">(</span><span class="n">shape</span><span class="o">=</span><span class="n">esp_flux</span><span class="o">.</span><span class="n">shape</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">esp_flux</span><span class="o">.</span><span class="n">dtype</span><span class="p">)</span>
<span class="gp">>>> </span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">esp_flux_av</span><span class="p">)):</span>
<span class="gp">... </span> <span class="n">esp_flux_av</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">scipy</span><span class="o">.</span><span class="n">stats</span><span class="o">.</span><span class="n">nanmean</span><span class="p">(</span><span class="n">esp_flux</span><span class="p">[</span><span class="nb">max</span><span class="p">(</span><span class="n">i</span> <span class="o">-</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span><span class="n">i</span> <span class="o">+</span> <span class="mi">14</span><span class="p">])</span>
</pre></div>
</div>
<p><a class="reference external" href="https://numpy.org/doc/stable/reference/generated/numpy.empty.html#numpy.empty" title="(in NumPy v2.1)"><code class="xref py py-func docutils literal notranslate"><span class="pre">numpy.empty()</span></code></a> creates an empty array, taking the <code class="docutils literal notranslate"><span class="pre">shape</span></code> and
<code class="docutils literal notranslate"><span class="pre">dtype</span></code> from the <code class="docutils literal notranslate"><span class="pre">esp_flux</span></code> array. <code class="docutils literal notranslate"><span class="pre">empty</span></code> does not initialize
the data in the array, so it is essentially random junk; use
<a class="reference external" href="https://numpy.org/doc/stable/reference/generated/numpy.zeros.html#numpy.zeros" title="(in NumPy v2.1)"><code class="xref py py-func docutils literal notranslate"><span class="pre">zeros()</span></code></a> to create an array filled with zeros.</p>
<p><a class="reference external" href="https://docs.python.org/3/library/functions.html#len" title="(in Python v3.13)"><code class="xref py py-func docutils literal notranslate"><span class="pre">len()</span></code></a> returns the length of an array, and <a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#range" title="(in Python v3.13)"><code class="xref py py-class docutils literal notranslate"><span class="pre">range</span></code></a> then
iterates over each number from 0 to length minus 1, i.e. the entire
array. Each element is then set to a 27-day average: from 13 days
before a day’s measurement through 13 days after. (Python slices do
not include the last element listed; they are half-open). Note that
these slices can happily run off the end of the <code class="docutils literal notranslate"><span class="pre">esp_flux</span></code> array,
but we use <a class="reference external" href="https://docs.python.org/3/library/functions.html#max" title="(in Python v3.13)"><code class="xref py py-func docutils literal notranslate"><span class="pre">max()</span></code></a> to ensure the first index does not go negative.
(Negative indices have special meaning in Python.)</p>
<p><code class="docutils literal notranslate"><span class="pre">scipy.stats.nanmean</span> <span class="pre">(deprecated</span> <span class="pre">in</span> <span class="pre">scipy</span> <span class="pre">0.18.0)</span></code> takes the mean of a numpy array,
but skips any elements with a value of “not a number” (nan), which is
often used for fill. (This is our first exposure to the <a class="reference external" href="https://docs.scipy.org/doc/scipy/index.html#module-scipy" title="(in SciPy v1.14.1)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">scipy</span></code></a>
module.)</p>
<p>For the solar wind averaging, the times need to cover the 24 * 13.5 = 324
hours previous, and 324 hours following (non-inclusive). There is also a
more efficient way than using an explicit loop:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">vsw_av</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">fromiter</span><span class="p">((</span><span class="n">scipy</span><span class="o">.</span><span class="n">stats</span><span class="o">.</span><span class="n">nanmean</span><span class="p">(</span><span class="n">vsw</span><span class="p">[</span><span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">i</span> <span class="o">-</span> <span class="mi">324</span><span class="p">):</span><span class="n">i</span> <span class="o">+</span> <span class="mi">324</span><span class="p">])</span>
<span class="gp">... </span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">vsw</span><span class="p">))),</span>
<span class="gp">... </span> <span class="n">count</span><span class="o">=</span><span class="nb">len</span><span class="p">(</span><span class="n">vsw</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">vsw</span><span class="o">.</span><span class="n">dtype</span><span class="p">)</span>
</pre></div>
</div>
<p><a class="reference external" href="https://numpy.org/doc/stable/reference/generated/numpy.fromiter.html#numpy.fromiter" title="(in NumPy v2.1)"><code class="xref py py-func docutils literal notranslate"><span class="pre">fromiter()</span></code></a> makes a numpy array from an <a class="reference external" href="http://docs.python.org/library/stdtypes.html#iterator-types">iterator</a>, which
is like a list except that it holds information on generating each
element in a sequence rather than creating the entire
sequence. <code class="docutils literal notranslate"><span class="pre">count</span></code> provides numpy with the number of elements in the
output (so it can make the entire array at once); <code class="docutils literal notranslate"><span class="pre">dtype</span></code> here is
just copied from the input.</p>
<p>The type of iterator used here is a <a class="reference external" href="http://www.python.org/dev/peps/pep-0289/">generator expression</a>, closely related to a
<a class="reference external" href="http://docs.python.org/tutorial/datastructures.html#list-comprehensions">list comprehension</a>.
These are among the most powerful and most difficult to understand
concepts in Python. An illustrative, although not useful, example:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="p">(</span><span class="n">x</span> <span class="o">+</span> <span class="mi">1</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">)):</span>
<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
</pre></div>
</div>
<p>Here <code class="docutils literal notranslate"><span class="pre">(x</span> <span class="pre">+</span> <span class="pre">1</span> <span class="pre">for</span> <span class="pre">x</span> <span class="pre">in</span> <span class="pre">range(10))</span></code> is a generator expression that
creates an iterator, which will return the numbers 1 through 10. At no
point is the complete list of all numbers constructed, saving memory.</p>
<p>In our calculation of <code class="docutils literal notranslate"><span class="pre">esp_flux_av</span></code>, we created an explicit loop in
Python. The generator expression used to compute <code class="docutils literal notranslate"><span class="pre">vsw_av</span></code> has no
explicit loop, and the actual looping is handled in (much faster)
compiled C code.</p>
</section>
<section id="making-figure-1">
<h2>Making Figure 1<a class="headerlink" href="#making-figure-1" title="Link to this heading">¶</a></h2>
<p>To actually plot, we need access to the <a class="reference external" href="https://matplotlib.org/stable/api/pyplot_summary.html#module-matplotlib.pyplot" title="(in Matplotlib v3.9.2)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">pyplot</span></code></a> module:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="nn">plt</span>
<span class="gp">>>> </span><span class="n">plt</span><span class="o">.</span><span class="n">ion</span><span class="p">()</span>
</pre></div>
</div>
<p>This alternate form of the import statement shouldn’t be overused (it can
make code harder to read by masking the origin of functions), but is
conventional for matplotlib.</p>
<p><a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.ion.html#matplotlib.pyplot.ion" title="(in Matplotlib v3.9.2)"><code class="xref py py-func docutils literal notranslate"><span class="pre">ion()</span></code></a> turns on interactive mode so plots appear
and are updated as they’re created.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">plt</span><span class="o">.</span><span class="n">semilogy</span><span class="p">(</span><span class="n">esp_times</span><span class="p">,</span> <span class="mi">10</span> <span class="o">**</span> <span class="n">esp_flux_av</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">plt</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
<span class="gp">>>> </span><span class="n">plt</span><span class="o">.</span><span class="n">draw</span><span class="p">()</span>
</pre></div>
</div>
<p><a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.semilogy.html#matplotlib.pyplot.semilogy" title="(in Matplotlib v3.9.2)"><code class="xref py py-func docutils literal notranslate"><span class="pre">semilogy()</span></code></a> creates a semilog plot, log
on the Y axis. The first two arguments are a list of X and Y values;
after that there are many options to specify formatting (such as the
color, used here.)</p>
<p>The ESP fluxes are stored as the log of the flux; <code class="docutils literal notranslate"><span class="pre">**</span></code> is the
exponentiation operator so the (geometric!) average is plotted
properly.</p>
<p><a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.draw.html#matplotlib.pyplot.draw" title="(in Matplotlib v3.9.2)"><code class="xref py py-func docutils literal notranslate"><span class="pre">draw()</span></code></a> draws the updated plot; sometimes it
needs to be called repeatedly. Use it whenever you want the plot updated;
it will not be included from here on.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">plt</span><span class="o">.</span><span class="n">xlabel</span><span class="p">(</span><span class="s1">'Year'</span><span class="p">,</span> <span class="n">weight</span><span class="o">=</span><span class="s1">'bold'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">plt</span><span class="o">.</span><span class="n">ylabel</span><span class="p">(</span><span class="s1">'Electron Flux</span><span class="se">\n</span><span class="s1">1.8-3.5 MeV'</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">'blue'</span><span class="p">,</span> <span class="n">weight</span><span class="o">=</span><span class="s1">'bold'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">plt</span><span class="o">.</span><span class="n">ylim</span><span class="p">(</span><span class="mf">1e-2</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
<span class="go">(0.01, 10)</span>
</pre></div>
</div>
<p><a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.xlabel.html#matplotlib.pyplot.xlabel" title="(in Matplotlib v3.9.2)"><code class="xref py py-func docutils literal notranslate"><span class="pre">xlabel()</span></code></a> and <a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.ylabel.html#matplotlib.pyplot.ylabel" title="(in Matplotlib v3.9.2)"><code class="xref py py-func docutils literal notranslate"><span class="pre">ylabel()</span></code></a>
set the labels for the axes. Note the newline (<code class="docutils literal notranslate"><span class="pre">\n</span></code>) in the string for
the Y label. <a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.ylim.html#matplotlib.pyplot.ylim" title="(in Matplotlib v3.9.2)"><code class="xref py py-func docutils literal notranslate"><span class="pre">ylim()</span></code></a> sets the lower and upper
limits for the Y axis; there is, of course, <a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.xlim.html#matplotlib.pyplot.xlim" title="(in Matplotlib v3.9.2)"><code class="xref py py-func docutils literal notranslate"><span class="pre">xlim()</span></code></a>
as well.</p>
<p>These are the simplest, although not most flexible, ways to work with plots.
To produce the full Figure 1, we’ll move out of interactive mode:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">plt</span><span class="o">.</span><span class="n">ioff</span><span class="p">()</span>
<span class="gp">>>> </span><span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
</pre></div>
</div>
<p><a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.ioff.html#matplotlib.pyplot.ioff" title="(in Matplotlib v3.9.2)"><code class="xref py py-func docutils literal notranslate"><span class="pre">ioff()</span></code></a> turns off interactive mode. Once
interactive mode is off, <a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.show.html#matplotlib.pyplot.show" title="(in Matplotlib v3.9.2)"><code class="xref py py-func docutils literal notranslate"><span class="pre">show()</span></code></a> displays
the full plot, including controls for panning, zooming, etc. Until
the plot is closed, nothing further can happen in the Python window.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">[</span><span class="mi">11</span><span class="p">,</span> <span class="mf">8.5</span><span class="p">])</span>
</pre></div>
</div>
<p><a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.figure.html#matplotlib.pyplot.figure" title="(in Matplotlib v3.9.2)"><code class="xref py py-func docutils literal notranslate"><span class="pre">figure()</span></code></a> creates a new
<a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.figure.Figure.html#matplotlib.figure.Figure" title="(in Matplotlib v3.9.2)"><code class="xref py py-class docutils literal notranslate"><span class="pre">Figure</span></code></a>; the size specified here is
US-letter paper, landscape orientation.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="o">.</span><span class="n">add_subplot</span><span class="p">(</span><span class="mi">111</span><span class="p">)</span>
</pre></div>
</div>
<p><a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.figure.Figure.add_subplot.html#matplotlib.figure.Figure.add_subplot" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">add_subplot()</span></code></a> creates an
<a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.html#matplotlib.axes.Axes" title="(in Matplotlib v3.9.2)"><code class="xref py py-class docutils literal notranslate"><span class="pre">Axes</span></code></a> object, which can contain an actual
plot. <code class="docutils literal notranslate"><span class="pre">111</span></code> here means that the figure will have 1 subplot and the
new subplot should be in position (1, 1); more on this later.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">fluxline</span> <span class="o">=</span> <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">esp_times</span><span class="p">,</span> <span class="mi">10</span> <span class="o">**</span> <span class="n">esp_flux_av</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">)</span>
</pre></div>
</div>
<p><a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.plot.html#matplotlib.axes.Axes.plot" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">plot()</span></code></a> puts the relevant data into the
plot; again specifying a blue line. It returns a list of
<a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.lines.Line2D.html#matplotlib.lines.Line2D" title="(in Matplotlib v3.9.2)"><code class="xref py py-class docutils literal notranslate"><span class="pre">Line2D</span></code></a> objects, which we save for later
use.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">ax</span><span class="o">.</span><span class="n">set_yscale</span><span class="p">(</span><span class="s1">'log'</span><span class="p">)</span>
</pre></div>
</div>
<p><a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_yscale.html#matplotlib.axes.Axes.set_yscale" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">set_yscale()</span></code></a> switches the Y axis between
log and linear (<a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_xscale.html#matplotlib.axes.Axes.set_xscale" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">set_xscale()</span></code></a> for the X axis).</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">ax</span><span class="o">.</span><span class="n">set_ylim</span><span class="p">(</span><span class="mf">1e-2</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ax</span><span class="o">.</span><span class="n">set_xlabel</span><span class="p">(</span><span class="s1">'Year'</span><span class="p">,</span> <span class="n">weight</span><span class="o">=</span><span class="s1">'bold'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ax</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">'Electron Flux</span><span class="se">\n</span><span class="s1">1.8-3.5 MeV'</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">'b'</span><span class="p">,</span> <span class="n">weight</span><span class="o">=</span><span class="s1">'bold'</span><span class="p">)</span>
</pre></div>
</div>
<p><a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_ylim.html#matplotlib.axes.Axes.set_ylim" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">set_ylim()</span></code></a> (and
<a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_xlim.html#matplotlib.axes.Axes.set_xlim" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">set_xlim()</span></code></a>),
<a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_xlabel.html#matplotlib.axes.Axes.set_xlabel" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">set_xlabel()</span></code></a>, and
<a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_ylabel.html#matplotlib.axes.Axes.set_ylabel" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">set_ylabel()</span></code></a> function much as above, but
operate on a particular <a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.html#matplotlib.axes.Axes" title="(in Matplotlib v3.9.2)"><code class="xref py py-class docutils literal notranslate"><span class="pre">Axes</span></code></a> object.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">ax2</span> <span class="o">=</span> <span class="n">ax</span><span class="o">.</span><span class="n">twinx</span><span class="p">()</span>
</pre></div>
</div>
<p><a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.twinx.html#matplotlib.axes.Axes.twinx" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">twinx()</span></code></a> establishes a second
Y axis (two values twinned on one X axis) on the same plot.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">vswline</span> <span class="o">=</span> <span class="n">ax2</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">vsw_times</span><span class="p">,</span> <span class="n">vsw_av</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ax2</span><span class="o">.</span><span class="n">set_ylim</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">650</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ax2</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">'Solar Wind Speed'</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">'r'</span><span class="p">,</span> <span class="n">rotation</span><span class="o">=</span><span class="mi">270</span><span class="p">,</span> <span class="n">weight</span><span class="o">=</span><span class="s1">'bold'</span><span class="p">)</span>
</pre></div>
</div>
<p>The resulting <a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.html#matplotlib.axes.Axes" title="(in Matplotlib v3.9.2)"><code class="xref py py-class docutils literal notranslate"><span class="pre">Axes</span></code></a> object has all the
methods that we’ve used before. Note <code class="docutils literal notranslate"><span class="pre">rotation</span></code> on
<a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_ylabel.html#matplotlib.axes.Axes.set_ylabel" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">set_ylabel()</span></code></a> to make the text run
top-to-bottom rather than bottom-to-top.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">ax</span><span class="o">.</span><span class="n">set_xlim</span><span class="p">(</span><span class="n">esp_times</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">esp_times</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<p>Since the solar wind data extends beyond the ESP data, this sets
the X axis to match the ESP data. Note <code class="docutils literal notranslate"><span class="pre">-1</span></code> to refer to the last
element of the array.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">leg</span> <span class="o">=</span> <span class="n">ax</span><span class="o">.</span><span class="n">legend</span><span class="p">([</span><span class="n">fluxline</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">vswline</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="p">[</span><span class="s1">'Flux'</span><span class="p">,</span> <span class="s1">'Vsw'</span><span class="p">],</span>
<span class="gp">... </span> <span class="n">loc</span><span class="o">=</span><span class="s1">'upper left'</span><span class="p">,</span> <span class="n">frameon</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</pre></div>
</div>
<p><a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.legend.html#matplotlib.axes.Axes.legend" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">legend()</span></code></a>, as may be expected, creates a
<a class="reference external" href="https://matplotlib.org/stable/api/legend_api.html#matplotlib.legend.Legend" title="(in Matplotlib v3.9.2)"><code class="xref py py-class docutils literal notranslate"><span class="pre">Legend</span></code></a> on the axes. The first parameter is
a list of the matplotlib objects to make a legend for; since the
plotting commands return these, we can pass them back in. Each plotting
command returns a <em>list</em>. In this case we just take the 0th element of
each list since we know there’s only one line from each plotting command.
The second parameter is the text used to annotate each line.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">fluxtext</span><span class="p">,</span> <span class="n">vswtext</span> <span class="o">=</span> <span class="n">leg</span><span class="o">.</span><span class="n">get_texts</span><span class="p">()</span>
<span class="gp">>>> </span><span class="n">fluxtext</span><span class="o">.</span><span class="n">set_color</span><span class="p">(</span><span class="n">fluxline</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">get_color</span><span class="p">())</span>
<span class="gp">>>> </span><span class="n">vswtext</span><span class="o">.</span><span class="n">set_color</span><span class="p">(</span><span class="n">vswline</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">get_color</span><span class="p">())</span>
</pre></div>
</div>
<p>The default text color is black, so we use
<a class="reference external" href="https://matplotlib.org/stable/api/legend_api.html#matplotlib.legend.Legend.get_texts" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_texts()</span></code></a> to get the
<a class="reference external" href="https://matplotlib.org/stable/api/text_api.html#matplotlib.text.Text" title="(in Matplotlib v3.9.2)"><code class="xref py py-class docutils literal notranslate"><span class="pre">Text</span></code></a> objects for the annotations. Again, we
know there are two (we just created the legend). Then
<a class="reference external" href="https://matplotlib.org/stable/api/text_api.html#matplotlib.text.Text.set_color" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">set_color()</span></code></a> sets the color based on the
the existing color for each line (<a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.lines.Line2D.html#matplotlib.lines.Line2D.get_color" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_color()</span></code></a>).</p>
<p>To see the results:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">plt</span><span class="o">.</span><span class="n">show</span><span class="p">()</span>
</pre></div>
</div>
<p>Close the window when done. Now we want to save the output:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">fig_fname</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">'..'</span><span class="p">,</span> <span class="s1">'plots'</span><span class="p">,</span> <span class="s1">'fig1a.eps'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">fig</span><span class="o">.</span><span class="n">savefig</span><span class="p">(</span><span class="n">fig_fname</span><span class="p">)</span>
</pre></div>
</div>
<p><a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.figure.Figure.savefig.html#matplotlib.figure.Figure.savefig" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">savefig()</span></code></a> saves the figure, in this case
as an encapsulated PostScript file (to the <code class="docutils literal notranslate"><span class="pre">plots</span></code> directory).</p>
<p>Let’s tweak a few things. For one, there’s a lot of padding around the figure,
which can make it difficult to properly scale for publication. The way around
this is to specify a <a class="reference external" href="https://matplotlib.org/stable/api/transformations.html#matplotlib.transforms.Bbox" title="(in Matplotlib v3.9.2)"><code class="xref py py-class docutils literal notranslate"><span class="pre">Bbox</span></code></a> (bounding box),
basically the lower left and upper right corners (in inches) to include
in the saved figure. Getting this right tends to be a matter of trial and error.
(<a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.figure.Figure.get_tightbbox.html#matplotlib.figure.Figure.get_tightbbox" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_tightbbox()</span></code></a> is supposed to help with this,
but it doesn’t quite work yet.)</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">matplotlib.transforms</span>
<span class="gp">>>> </span><span class="n">bob</span> <span class="o">=</span> <span class="n">matplotlib</span><span class="o">.</span><span class="n">transforms</span><span class="o">.</span><span class="n">Bbox</span><span class="p">([[</span><span class="mf">0.52</span><span class="p">,</span> <span class="mf">0.35</span><span class="p">],</span> <span class="p">[</span><span class="mf">10.5</span><span class="p">,</span> <span class="mf">7.95</span><span class="p">]])</span>
<span class="gp">>>> </span><span class="n">fig</span><span class="o">.</span><span class="n">savefig</span><span class="p">(</span><span class="n">fig_fname</span><span class="p">,</span> <span class="n">bbox_inches</span><span class="o">=</span><span class="n">bob</span><span class="p">,</span> <span class="n">pad_inches</span><span class="o">=</span><span class="mf">0.0</span><span class="p">)</span>
</pre></div>
</div>
<p>Better, but all the text is awfully small. Once the figure is fit in the paper
it’ll be really small. And the font isn’t that great.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">matplotlib</span>
<span class="gp">>>> </span><span class="n">matplotlib</span><span class="o">.</span><span class="n">rcParams</span><span class="p">[</span><span class="s1">'axes.unicode_minus'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
<span class="gp">>>> </span><span class="n">matplotlib</span><span class="o">.</span><span class="n">rcParams</span><span class="p">[</span><span class="s1">'text.usetex'</span><span class="p">]</span><span class="o">=</span> <span class="kc">True</span>
<span class="gp">>>> </span><span class="n">matplotlib</span><span class="o">.</span><span class="n">rcParams</span><span class="p">[</span><span class="s1">'font.family'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'serif'</span>
<span class="gp">>>> </span><span class="n">matplotlib</span><span class="o">.</span><span class="n">rcParams</span><span class="p">[</span><span class="s1">'font.size'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">14</span>
<span class="gp">>>> </span><span class="n">bob</span> <span class="o">=</span> <span class="n">matplotlib</span><span class="o">.</span><span class="n">transforms</span><span class="o">.</span><span class="n">Bbox</span><span class="p">([[</span><span class="mf">0.4</span><span class="p">,</span> <span class="mf">0.35</span><span class="p">],</span> <span class="p">[</span><span class="mf">10.7</span><span class="p">,</span> <span class="mf">7.95</span><span class="p">]])</span>
<span class="gp">>>> </span><span class="n">fig</span><span class="o">.</span><span class="n">savefig</span><span class="p">(</span><span class="n">fig_fname</span><span class="p">,</span> <span class="n">bbox_inches</span><span class="o">=</span><span class="n">bob</span><span class="p">,</span> <span class="n">pad_inches</span><span class="o">=</span><span class="mf">0.0</span><span class="p">)</span>
</pre></div>
</div>
<p>Now the font is bigger and it’s rendered using TeX, which should match
the body of the paper better (assuming the paper is in LaTeX). The
larger font means tweaking the bounding box. <code class="docutils literal notranslate"><span class="pre">unicode_minus</span></code> fixes a
problem where negative numbers on the axis don’t render properly in
TeX. Matplotlib has many more options for <a class="reference external" href="http://matplotlib.sourceforge.net/users/customizing.html">customization</a>.</p>
<p>The end result is a nice figure that can be printed full-size, put in
a PDF, or included directly in a paper.</p>
<p>Now we need the bottom half of Figure 1. From
<a class="reference external" href="http://www.sidc.be/silso/versionarchive">SIDC</a>, download the “Monthly mean total sunspot number” (<code class="docutils literal notranslate"><span class="pre">monthssn.dat</span></code>). Put it in the <code class="docutils literal notranslate"><span class="pre">data</span></code>
directory.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">bisect</span>
<span class="gp">>>> </span><span class="kn">import</span> <span class="nn">datetime</span>
<span class="gp">>>> </span><span class="n">monthfile</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">common</span><span class="o">.</span><span class="n">datadir</span><span class="p">,</span> <span class="s1">'monthssn.dat'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">convert</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="s1">'%Y%m'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ssn_data</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">genfromtxt</span><span class="p">(</span><span class="n">monthfile</span><span class="p">,</span> <span class="n">skip_header</span><span class="o">=</span><span class="mi">2400</span><span class="p">,</span> <span class="n">usecols</span><span class="o">=</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
<span class="gp">... </span> <span class="n">converters</span><span class="o">=</span><span class="p">{</span><span class="mi">0</span><span class="p">:</span> <span class="n">convert</span><span class="p">},</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">object</span><span class="p">,</span>
<span class="gp">... </span> <span class="n">skip_footer</span><span class="o">=</span><span class="mi">24</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">idx</span> <span class="o">=</span> <span class="n">bisect</span><span class="o">.</span><span class="n">bisect_left</span><span class="p">(</span><span class="n">ssn_data</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">(</span><span class="mi">1989</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
<span class="gp">>>> </span><span class="n">ssn_data</span> <span class="o">=</span> <span class="n">ssn_data</span><span class="p">[</span><span class="n">idx</span><span class="p">:]</span>
<span class="gp">>>> </span><span class="n">ssn_times</span> <span class="o">=</span> <span class="n">ssn_data</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">]</span>
<span class="gp">>>> </span><span class="n">ssn</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">ssn_data</span><span class="p">[:,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">float64</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">smooth_ssn</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">ssn_data</span><span class="p">[:,</span> <span class="mi">2</span><span class="p">],</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">float64</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ssn_times</span> <span class="o">+=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">(</span><span class="n">days</span><span class="o">=</span><span class="mi">15</span><span class="p">)</span>
</pre></div>
</div>
<p>Much of this should be familiar. <a class="reference external" href="https://numpy.org/doc/stable/reference/generated/numpy.genfromtxt.html#numpy.genfromtxt" title="(in NumPy v2.1)"><code class="xref py py-func docutils literal notranslate"><span class="pre">genfromtxt()</span></code></a> is a little more
flexible than <a class="reference external" href="https://numpy.org/doc/stable/reference/generated/numpy.loadtxt.html#numpy.loadtxt" title="(in NumPy v2.1)"><code class="xref py py-func docutils literal notranslate"><span class="pre">loadtxt()</span></code></a>; here it allows the skipping of lines
at the end as well as the beginning (skipping 200 years at the start, 2 at
the end, where data are provisional.) Here we load both times and the
sunspot numbers in the same command so that if any lines don’t load, they
will not wind up in any of the arrays.</p>
<p><a class="reference external" href="https://docs.python.org/3/library/bisect.html#module-bisect" title="(in Python v3.13)"><code class="xref py py-mod docutils literal notranslate"><span class="pre">bisect</span></code></a> provides fast functions for searching in sorted data;
<a class="reference external" href="https://docs.python.org/3/library/bisect.html#bisect.bisect_left" title="(in Python v3.13)"><code class="xref py py-func docutils literal notranslate"><span class="pre">bisect_left()</span></code></a> is roughly a find-the-position-of function.
Having found the position of the start of 1989, we then keep times
from then on (specifying a start index without a stop index in Python
means “from start to end of the list.”) Note that, although <code class="docutils literal notranslate"><span class="pre">bisect</span></code>
is meant to work on lists, it also works fine on numpy arrays; this is a
common feature of Python known as
<a class="reference external" href="http://en.wikipedia.org/wiki/Duck_typing#In_Python">duck typing</a>.</p>
<p>We then use <a class="reference external" href="https://numpy.org/doc/stable/reference/generated/numpy.asarray.html#numpy.asarray" title="(in NumPy v2.1)"><code class="xref py py-func docutils literal notranslate"><span class="pre">asarray()</span></code></a>
to convert the <code class="docutils literal notranslate"><span class="pre">ssn</span></code> and <code class="docutils literal notranslate"><span class="pre">smooth_ssn</span></code> columns to float arrays. Note
the slice notation: <code class="docutils literal notranslate"><span class="pre">[:,</span> <span class="pre">0]</span></code> means take all indices of the first dimension
(line number) and only the 0th index of the second dimension (column in the
line). Finally, we use <a class="reference external" href="https://docs.python.org/3/library/datetime.html#datetime.timedelta" title="(in Python v3.13)"><code class="xref py py-class docutils literal notranslate"><span class="pre">timedelta</span></code></a> to shift the date
associated with a month from the beginning to roughly the middle of the month.
Adding a scalar to an array does an element-wise addition.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">matplotlib.figure</span>
<span class="gp">>>> </span><span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">[</span><span class="mi">11</span><span class="p">,</span> <span class="mf">8.5</span><span class="p">],</span>
<span class="gp">... </span> <span class="n">subplotpars</span><span class="o">=</span><span class="n">matplotlib</span><span class="o">.</span><span class="n">figure</span><span class="o">.</span><span class="n">SubplotParams</span><span class="p">(</span><span class="n">hspace</span><span class="o">=</span><span class="mf">0.1</span><span class="p">))</span>
<span class="gp">>>> </span><span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="o">.</span><span class="n">add_subplot</span><span class="p">(</span><span class="mi">211</span><span class="p">)</span>
</pre></div>
</div>
<p>When creating the figure this time, we use
<code class="docutils literal notranslate"><span class="pre">matplotlib.figure.SubplotParams</span></code> to choose a slightly smaller
vertical spacing between adjacent subplots. Tweaking <code class="docutils literal notranslate"><span class="pre">SubplotParams</span></code>
also provides an alternative to tweaking bounding boxes.</p>
<p>Then we create a subplot with the information that there will be 2 rows, 1
column, and this is the first subplot. Now everything acting on ax, above,
can be repeated, although we skip setting the xlabel since only the bottom
axis will be labeled.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">fluxline</span> <span class="o">=</span> <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">esp_times</span><span class="p">,</span> <span class="mi">10</span> <span class="o">**</span> <span class="n">esp_flux_av</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ax</span><span class="o">.</span><span class="n">set_yscale</span><span class="p">(</span><span class="s1">'log'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ax</span><span class="o">.</span><span class="n">set_ylim</span><span class="p">(</span><span class="mf">1e-2</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ax</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">'Electron Flux</span><span class="se">\n</span><span class="s1">1.8-3.5 MeV'</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">'b'</span><span class="p">,</span> <span class="n">weight</span><span class="o">=</span><span class="s1">'bold'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ax2</span> <span class="o">=</span> <span class="n">ax</span><span class="o">.</span><span class="n">twinx</span><span class="p">()</span>
<span class="gp">>>> </span><span class="n">vswline</span> <span class="o">=</span> <span class="n">ax2</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">vsw_times</span><span class="p">,</span> <span class="n">vsw_av</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ax2</span><span class="o">.</span><span class="n">set_ylim</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">650</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ax2</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">'Solar Wind Speed'</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">'r'</span><span class="p">,</span> <span class="n">rotation</span><span class="o">=</span><span class="mi">270</span><span class="p">,</span> <span class="n">weight</span><span class="o">=</span><span class="s1">'bold'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ax</span><span class="o">.</span><span class="n">set_xlim</span><span class="p">(</span><span class="n">esp_times</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">esp_times</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="gp">>>> </span><span class="n">leg</span> <span class="o">=</span> <span class="n">ax</span><span class="o">.</span><span class="n">legend</span><span class="p">([</span><span class="n">fluxline</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">vswline</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="p">[</span><span class="s1">'Flux'</span><span class="p">,</span> <span class="s1">'Vsw'</span><span class="p">],</span>
<span class="gp">... </span> <span class="n">loc</span><span class="o">=</span><span class="s1">'upper left'</span><span class="p">,</span> <span class="n">frameon</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">fluxtext</span><span class="p">,</span> <span class="n">vswtext</span> <span class="o">=</span> <span class="n">leg</span><span class="o">.</span><span class="n">get_texts</span><span class="p">()</span>
<span class="gp">>>> </span><span class="n">fluxtext</span><span class="o">.</span><span class="n">set_color</span><span class="p">(</span><span class="n">fluxline</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">get_color</span><span class="p">())</span>
<span class="gp">>>> </span><span class="n">vswtext</span><span class="o">.</span><span class="n">set_color</span><span class="p">(</span><span class="n">vswline</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">get_color</span><span class="p">())</span>
</pre></div>
</div>
<p>Then we move on to adding the solar wind:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">ax3</span> <span class="o">=</span> <span class="n">fig</span><span class="o">.</span><span class="n">add_subplot</span><span class="p">(</span><span class="mi">212</span><span class="p">,</span> <span class="n">sharex</span><span class="o">=</span><span class="n">ax</span><span class="p">)</span>
</pre></div>
</div>
<p>This adds another subplot, the second in the 2x1 array. Its x axis is
shared with the existing <code class="docutils literal notranslate"><span class="pre">ax</span></code>. (This is poorly documented; see this
<a class="reference external" href="http://matplotlib.sourceforge.net/examples/pylab_examples/shared_axis_demo.html">example</a>)</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">plt</span><span class="o">.</span><span class="n">setp</span><span class="p">(</span><span class="n">ax</span><span class="o">.</span><span class="n">get_xticklabels</span><span class="p">(),</span> <span class="n">visible</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">plt</span><span class="o">.</span><span class="n">setp</span><span class="p">(</span><span class="n">ax2</span><span class="o">.</span><span class="n">get_xticklabels</span><span class="p">(),</span> <span class="n">visible</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
</pre></div>
</div>
<p><a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.setp.html#matplotlib.pyplot.setp" title="(in Matplotlib v3.9.2)"><code class="xref py py-func docutils literal notranslate"><span class="pre">setp()</span></code></a> sets a
property. <a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.get_xticklabels.html#matplotlib.axes.Axes.get_xticklabels" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_xticklabels()</span></code></a> returns all the
tick labels (<a class="reference external" href="https://matplotlib.org/stable/api/text_api.html#matplotlib.text.Text" title="(in Matplotlib v3.9.2)"><code class="xref py py-class docutils literal notranslate"><span class="pre">Text</span></code></a>) for the x axis; <code class="docutils literal notranslate"><span class="pre">setp</span></code>
then sets <code class="docutils literal notranslate"><span class="pre">visible</span></code> to <code class="docutils literal notranslate"><span class="pre">False</span></code> for all of them. This hides the
labeling on the axis for the upper subfigure.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">ax3</span><span class="o">.</span><span class="n">set_xlabel</span><span class="p">(</span><span class="s1">'Year'</span><span class="p">,</span> <span class="n">weight</span><span class="o">=</span><span class="s1">'bold'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ax3</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">'Sunspot Number'</span><span class="p">,</span> <span class="n">weight</span><span class="o">=</span><span class="s1">'bold'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">smoothline</span> <span class="o">=</span> <span class="n">ax3</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ssn_times</span><span class="p">,</span> <span class="n">smooth_ssn</span><span class="p">,</span> <span class="n">lw</span><span class="o">=</span><span class="mf">2.0</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">'k'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ssnline</span> <span class="o">=</span> <span class="n">ax3</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ssn_times</span><span class="p">,</span> <span class="n">ssn</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">'k'</span><span class="p">,</span> <span class="n">linestyle</span><span class="o">=</span><span class="s1">'dotted'</span><span class="p">)</span>
</pre></div>
</div>
<p>There is nothing new here except for the specifications of <code class="docutils literal notranslate"><span class="pre">linewidth</span></code>
and <code class="docutils literal notranslate"><span class="pre">linestyle</span></code>; see <a class="reference external" href="https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.plot.html#matplotlib.axes.Axes.plot" title="(in Matplotlib v3.9.2)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">plot()</span></code></a> for details.
Note <code class="docutils literal notranslate"><span class="pre">k</span></code> as the abbreviation for black (to avoid confusion with blue.)</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">leg2</span> <span class="o">=</span> <span class="n">ax3</span><span class="o">.</span><span class="n">legend</span><span class="p">([</span><span class="n">ssnline</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">smoothline</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span>
<span class="gp">... </span> <span class="p">[</span><span class="s1">'Sunspot Number'</span><span class="p">,</span> <span class="s1">'Smoothed SSN'</span><span class="p">],</span>
<span class="gp">... </span> <span class="n">loc</span><span class="o">=</span><span class="s1">'upper right'</span><span class="p">,</span> <span class="n">frameon</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ax3</span><span class="o">.</span><span class="n">set_ylim</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">200</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">ax3</span><span class="o">.</span><span class="n">set_xlim</span><span class="p">(</span><span class="n">esp_times</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">esp_times</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
</pre></div>
</div>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">fig_fname</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">'..'</span><span class="p">,</span> <span class="s1">'plots'</span><span class="p">,</span> <span class="s1">'fig1.eps'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">fig</span><span class="o">.</span><span class="n">savefig</span><span class="p">(</span><span class="n">fig_fname</span><span class="p">,</span> <span class="n">bbox_inches</span><span class="o">=</span><span class="n">bob</span><span class="p">,</span> <span class="n">pad_inches</span><span class="o">=</span><span class="mf">0.0</span><span class="p">)</span>
</pre></div>
</div>
<p>All of this has been seen for the top half of figure 1.</p>
<p>Following is the complete code to reproduce Figure 1.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">bisect</span>
<span class="kn">import</span> <span class="nn">datetime</span>
<span class="kn">import</span> <span class="nn">os.path</span>
<span class="kn">import</span> <span class="nn">common</span>
<span class="kn">import</span> <span class="nn">matplotlib</span>
<span class="kn">import</span> <span class="nn">matplotlib.figure</span>
<span class="kn">import</span> <span class="nn">matplotlib.pyplot</span> <span class="k">as</span> <span class="nn">plt</span>
<span class="kn">import</span> <span class="nn">matplotlib.transforms</span>
<span class="kn">import</span> <span class="nn">numpy</span>
<span class="kn">import</span> <span class="nn">scipy</span>
<span class="kn">import</span> <span class="nn">scipy.stats</span>
<span class="kn">import</span> <span class="nn">spacepy.omni</span>
<span class="kn">import</span> <span class="nn">spacepy.time</span>
<span class="n">matplotlib</span><span class="o">.</span><span class="n">rcParams</span><span class="p">[</span><span class="s1">'axes.unicode_minus'</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">matplotlib</span><span class="o">.</span><span class="n">rcParams</span><span class="p">[</span><span class="s1">'text.usetex'</span><span class="p">]</span><span class="o">=</span> <span class="kc">True</span>
<span class="n">matplotlib</span><span class="o">.</span><span class="n">rcParams</span><span class="p">[</span><span class="s1">'font.family'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'serif'</span>
<span class="n">matplotlib</span><span class="o">.</span><span class="n">rcParams</span><span class="p">[</span><span class="s1">'font.size'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">14</span>
<span class="n">bob</span> <span class="o">=</span> <span class="n">matplotlib</span><span class="o">.</span><span class="n">transforms</span><span class="o">.</span><span class="n">Bbox</span><span class="p">([[</span><span class="mf">0.4</span><span class="p">,</span> <span class="mf">0.35</span><span class="p">],</span> <span class="p">[</span><span class="mf">10.7</span><span class="p">,</span> <span class="mf">7.95</span><span class="p">]])</span>
<span class="n">times</span> <span class="o">=</span> <span class="n">spacepy</span><span class="o">.</span><span class="n">time</span><span class="o">.</span><span class="n">tickrange</span><span class="p">(</span><span class="s1">'1989-01-01'</span><span class="p">,</span> <span class="s1">'2011-01-01'</span><span class="p">,</span>
<span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">(</span><span class="n">hours</span><span class="o">=</span><span class="mi">1</span><span class="p">))</span>
<span class="n">d</span> <span class="o">=</span> <span class="n">spacepy</span><span class="o">.</span><span class="n">omni</span><span class="o">.</span><span class="n">get_omni</span><span class="p">(</span><span class="n">times</span><span class="p">)</span>
<span class="n">vsw</span> <span class="o">=</span> <span class="n">d</span><span class="p">[</span><span class="s1">'velo'</span><span class="p">]</span>
<span class="n">vsw_times</span> <span class="o">=</span> <span class="n">d</span><span class="p">[</span><span class="s1">'UTC'</span><span class="p">]</span>
<span class="n">esp_times</span><span class="p">,</span> <span class="n">esp_flux</span> <span class="o">=</span> <span class="n">common</span><span class="o">.</span><span class="n">load_esp</span><span class="p">()</span>
<span class="n">esp_flux_av</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">empty</span><span class="p">(</span><span class="n">shape</span><span class="o">=</span><span class="n">esp_flux</span><span class="o">.</span><span class="n">shape</span><span class="p">,</span> <span class="n">dtype</span><span class="o">=</span><span class="n">esp_flux</span><span class="o">.</span><span class="n">dtype</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">esp_flux_av</span><span class="p">)):</span>
<span class="n">esp_flux_av</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">scipy</span><span class="o">.</span><span class="n">stats</span><span class="o">.</span><span class="n">nanmean</span><span class="p">(</span><span class="n">esp_flux</span><span class="p">[</span><span class="nb">max</span><span class="p">(</span><span class="n">i</span> <span class="o">-</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">0</span><span class="p">):</span><span class="n">i</span> <span class="o">+</span> <span class="mi">14</span><span class="p">])</span>
<span class="n">vsw_av</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">fromiter</span><span class="p">((</span><span class="n">scipy</span><span class="o">.</span><span class="n">stats</span><span class="o">.</span><span class="n">nanmean</span><span class="p">(</span><span class="n">vsw</span><span class="p">[</span><span class="nb">max</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">i</span> <span class="o">-</span> <span class="mi">324</span><span class="p">):</span><span class="n">i</span> <span class="o">+</span> <span class="mi">324</span><span class="p">])</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">vsw</span><span class="p">))),</span>
<span class="n">count</span><span class="o">=</span><span class="nb">len</span><span class="p">(</span><span class="n">vsw</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">vsw</span><span class="o">.</span><span class="n">dtype</span><span class="p">)</span>
<span class="n">monthfile</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">common</span><span class="o">.</span><span class="n">datadir</span><span class="p">,</span> <span class="s1">'monthssn.dat'</span><span class="p">)</span>
<span class="n">convert</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="s1">'%Y%m'</span><span class="p">)</span>
<span class="n">ssn_data</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">genfromtxt</span><span class="p">(</span><span class="n">monthfile</span><span class="p">,</span> <span class="n">skip_header</span><span class="o">=</span><span class="mi">2400</span><span class="p">,</span> <span class="n">usecols</span><span class="o">=</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
<span class="n">converters</span><span class="o">=</span><span class="p">{</span><span class="mi">0</span><span class="p">:</span> <span class="n">convert</span><span class="p">},</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">object</span><span class="p">,</span>
<span class="n">skip_footer</span><span class="o">=</span><span class="mi">24</span><span class="p">)</span>
<span class="n">idx</span> <span class="o">=</span> <span class="n">bisect</span><span class="o">.</span><span class="n">bisect_left</span><span class="p">(</span><span class="n">ssn_data</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">],</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">(</span><span class="mi">1989</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
<span class="n">ssn_data</span> <span class="o">=</span> <span class="n">ssn_data</span><span class="p">[</span><span class="n">idx</span><span class="p">:]</span>
<span class="n">ssn_times</span> <span class="o">=</span> <span class="n">ssn_data</span><span class="p">[:,</span> <span class="mi">0</span><span class="p">]</span>
<span class="n">ssn</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">ssn_data</span><span class="p">[:,</span> <span class="mi">1</span><span class="p">],</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">float64</span><span class="p">)</span>
<span class="n">smooth_ssn</span> <span class="o">=</span> <span class="n">numpy</span><span class="o">.</span><span class="n">asarray</span><span class="p">(</span><span class="n">ssn_data</span><span class="p">[:,</span> <span class="mi">2</span><span class="p">],</span> <span class="n">dtype</span><span class="o">=</span><span class="n">numpy</span><span class="o">.</span><span class="n">float64</span><span class="p">)</span>
<span class="n">ssn_times</span> <span class="o">+=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">(</span><span class="n">days</span><span class="o">=</span><span class="mi">15</span><span class="p">)</span>
<span class="n">fig</span> <span class="o">=</span> <span class="n">plt</span><span class="o">.</span><span class="n">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">[</span><span class="mi">11</span><span class="p">,</span> <span class="mf">8.5</span><span class="p">],</span>
<span class="n">subplotpars</span><span class="o">=</span><span class="n">matplotlib</span><span class="o">.</span><span class="n">figure</span><span class="o">.</span><span class="n">SubplotParams</span><span class="p">(</span><span class="n">hspace</span><span class="o">=</span><span class="mf">0.1</span><span class="p">))</span>
<span class="n">ax</span> <span class="o">=</span> <span class="n">fig</span><span class="o">.</span><span class="n">add_subplot</span><span class="p">(</span><span class="mi">211</span><span class="p">)</span>
<span class="n">fluxline</span> <span class="o">=</span> <span class="n">ax</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">esp_times</span><span class="p">,</span> <span class="mi">10</span> <span class="o">**</span> <span class="n">esp_flux_av</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">)</span>
<span class="n">ax</span><span class="o">.</span><span class="n">set_yscale</span><span class="p">(</span><span class="s1">'log'</span><span class="p">)</span>
<span class="n">ax</span><span class="o">.</span><span class="n">set_ylim</span><span class="p">(</span><span class="mf">1e-2</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
<span class="n">ax</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">'Electron Flux</span><span class="se">\n</span><span class="s1">1.8-3.5 MeV'</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">'b'</span><span class="p">,</span> <span class="n">weight</span><span class="o">=</span><span class="s1">'bold'</span><span class="p">)</span>
<span class="n">ax2</span> <span class="o">=</span> <span class="n">ax</span><span class="o">.</span><span class="n">twinx</span><span class="p">()</span>
<span class="n">vswline</span> <span class="o">=</span> <span class="n">ax2</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">vsw_times</span><span class="p">,</span> <span class="n">vsw_av</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">)</span>
<span class="n">ax2</span><span class="o">.</span><span class="n">set_ylim</span><span class="p">(</span><span class="mi">300</span><span class="p">,</span> <span class="mi">650</span><span class="p">)</span>
<span class="n">ax2</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">'Solar Wind Speed'</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">'r'</span><span class="p">,</span> <span class="n">rotation</span><span class="o">=</span><span class="mi">270</span><span class="p">,</span> <span class="n">weight</span><span class="o">=</span><span class="s1">'bold'</span><span class="p">)</span>
<span class="n">ax</span><span class="o">.</span><span class="n">set_xlim</span><span class="p">(</span><span class="n">esp_times</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">esp_times</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">leg</span> <span class="o">=</span> <span class="n">ax</span><span class="o">.</span><span class="n">legend</span><span class="p">([</span><span class="n">fluxline</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">vswline</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span> <span class="p">[</span><span class="s1">'Flux'</span><span class="p">,</span> <span class="s1">'Vsw'</span><span class="p">],</span>
<span class="n">loc</span><span class="o">=</span><span class="s1">'upper left'</span><span class="p">,</span> <span class="n">frameon</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">fluxtext</span><span class="p">,</span> <span class="n">vswtext</span> <span class="o">=</span> <span class="n">leg</span><span class="o">.</span><span class="n">get_texts</span><span class="p">()</span>
<span class="n">fluxtext</span><span class="o">.</span><span class="n">set_color</span><span class="p">(</span><span class="n">fluxline</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">get_color</span><span class="p">())</span>
<span class="n">vswtext</span><span class="o">.</span><span class="n">set_color</span><span class="p">(</span><span class="n">vswline</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">get_color</span><span class="p">())</span>
<span class="n">ax3</span> <span class="o">=</span> <span class="n">fig</span><span class="o">.</span><span class="n">add_subplot</span><span class="p">(</span><span class="mi">212</span><span class="p">,</span> <span class="n">sharex</span><span class="o">=</span><span class="n">ax</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">setp</span><span class="p">(</span><span class="n">ax</span><span class="o">.</span><span class="n">get_xticklabels</span><span class="p">(),</span> <span class="n">visible</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">plt</span><span class="o">.</span><span class="n">setp</span><span class="p">(</span><span class="n">ax2</span><span class="o">.</span><span class="n">get_xticklabels</span><span class="p">(),</span> <span class="n">visible</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">ax3</span><span class="o">.</span><span class="n">set_xlabel</span><span class="p">(</span><span class="s1">'Year'</span><span class="p">,</span> <span class="n">weight</span><span class="o">=</span><span class="s1">'bold'</span><span class="p">)</span>
<span class="n">ax3</span><span class="o">.</span><span class="n">set_ylabel</span><span class="p">(</span><span class="s1">'Sunspot Number'</span><span class="p">,</span> <span class="n">weight</span><span class="o">=</span><span class="s1">'bold'</span><span class="p">)</span>
<span class="n">smoothline</span> <span class="o">=</span> <span class="n">ax3</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ssn_times</span><span class="p">,</span> <span class="n">smooth_ssn</span><span class="p">,</span> <span class="n">lw</span><span class="o">=</span><span class="mf">2.0</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">'k'</span><span class="p">)</span>
<span class="n">ssnline</span> <span class="o">=</span> <span class="n">ax3</span><span class="o">.</span><span class="n">plot</span><span class="p">(</span><span class="n">ssn_times</span><span class="p">,</span> <span class="n">ssn</span><span class="p">,</span> <span class="n">color</span><span class="o">=</span><span class="s1">'k'</span><span class="p">,</span> <span class="n">linestyle</span><span class="o">=</span><span class="s1">'dotted'</span><span class="p">)</span>
<span class="n">leg2</span> <span class="o">=</span> <span class="n">ax3</span><span class="o">.</span><span class="n">legend</span><span class="p">([</span><span class="n">ssnline</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">smoothline</span><span class="p">[</span><span class="mi">0</span><span class="p">]],</span>
<span class="p">[</span><span class="s1">'Sunspot Number'</span><span class="p">,</span> <span class="s1">'Smoothed SSN'</span><span class="p">],</span>
<span class="n">loc</span><span class="o">=</span><span class="s1">'upper right'</span><span class="p">,</span> <span class="n">frameon</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
<span class="n">ax3</span><span class="o">.</span><span class="n">set_ylim</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">200</span><span class="p">)</span>
<span class="n">ax3</span><span class="o">.</span><span class="n">set_xlim</span><span class="p">(</span><span class="n">esp_times</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">esp_times</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span>
<span class="n">fig_fname</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">'..'</span><span class="p">,</span> <span class="s1">'plots'</span><span class="p">,</span> <span class="s1">'fig1.eps'</span><span class="p">)</span>
<span class="n">fig</span><span class="o">.</span><span class="n">savefig</span><span class="p">(</span><span class="n">fig_fname</span><span class="p">,</span> <span class="n">bbox_inches</span><span class="o">=</span><span class="n">bob</span><span class="p">,</span> <span class="n">pad_inches</span><span class="o">=</span><span class="mf">0.0</span><span class="p">)</span>
</pre></div>
</div>
</section>
<section id="appendix-fixing-the-esp-data-file">
<span id="appendix"></span><h2>Appendix: Fixing the ESP data file<a class="headerlink" href="#appendix-fixing-the-esp-data-file" title="Link to this heading">¶</a></h2>
<p>This appendix provides a detailed explanation of the script that fixes
the ESP data file.</p>
<p>First set up a variable to hold the location of the data, as above:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">os.path</span>
<span class="gp">>>> </span><span class="n">datadir</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">'..'</span><span class="p">,</span> <span class="s1">'data'</span><span class="p">)</span>
</pre></div>
</div>
<p>Examining the data file, it is clear that something is odd: lines
appear to have been broken inappropriately; for example, the data for
1989-10-12 are split across two lines. So the first task is to fix
this file, first opening the original (broken) file and an output
(fixed) file:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">in_name</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">datadir</span><span class="p">,</span> <span class="s1">'jgra20797-sup-0003-ds01.txt'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">out_name</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">datadir</span><span class="p">,</span> <span class="s1">'jgra20797-sup-0003-ds01_FIXED.txt'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">infile</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">in_name</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">outfile</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">out_name</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span>
</pre></div>
</div>
<p>These lines <a class="reference external" href="https://docs.python.org/3/library/functions.html#open" title="(in Python v3.13)"><code class="xref py py-func docutils literal notranslate"><span class="pre">open()</span></code></a> the original file for reading (<code class="docutils literal notranslate"><span class="pre">r</span></code>), and a
new file for writing (<code class="docutils literal notranslate"><span class="pre">w</span></code>). Note that opening a file for writing
will destroy any existing contents.</p>
<p>The file happens to contain a mixture of carriage returns and proper newlines, so to begin all the carriage returns need to be rewritten as newlines:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">data</span> <span class="o">=</span> <span class="n">infile</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="gp">>>> </span><span class="n">infile</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="gp">>>> </span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'</span><span class="se">\r</span><span class="s1">'</span><span class="p">,</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">'</span><span class="se">\n\n</span><span class="s1">'</span><span class="p">,</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">file.read()</span></code> reads <em>all</em> data from the file at once, so this is
not recommended for large files. In this case it makes things
easier. Once the data are read, <code class="docutils literal notranslate"><span class="pre">file.close()</span></code> the file. Calling
the <a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str.replace" title="(in Python v3.13)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">replace()</span></code></a> method on <code class="docutils literal notranslate"><span class="pre">data</span></code> replaces all instances of
the first parameter (<code class="docutils literal notranslate"><span class="pre">'\r'</span></code>) with the second (<code class="docutils literal notranslate"><span class="pre">'\n'</span></code>). <code class="docutils literal notranslate"><span class="pre">\r</span></code> is
the special code indicating a carriage return; <code class="docutils literal notranslate"><span class="pre">\n</span></code>, a newline. For
a literal backslash, use <code class="docutils literal notranslate"><span class="pre">\\</span></code>. Once the carriage returns have been
replaced with newlines, a second round of replacement eliminates
duplicates.</p>
<p>Now that the line endings have been cleaned up, it’s time to rejoin the erroneously split lines. First copy over the 15 lines of header verbatim:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">15</span><span class="p">):</span>
<span class="gp">... </span> <span class="n">outfile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">+</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
</pre></div>
</div>
<p><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str.split" title="(in Python v3.13)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">split()</span></code></a> splits a string into a <a class="reference external" href="http://docs.python.org/tutorial/introduction.html#lists">list</a>, with the
split between elements happening wherever the provided parameter
occurs. A simple example:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">foo</span> <span class="o">=</span> <span class="s1">'a.b.c'</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'.'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span>
<span class="go">['a', 'b', 'c']</span>
</pre></div>
</div>
<p>The splitting character is not present in the output.</p>
<p>The advantage of a list is that it makes it easy to access individual elements:
>>> print(foo[1])
b</p>
<p>The first element of a Python list is numbered zero.</p>
<p><a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#range" title="(in Python v3.13)"><code class="xref py py-class docutils literal notranslate"><span class="pre">range</span></code></a> returns a list of numbers, starting from 0, with the parameter specifying how many elements are in the list:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nb">print</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">5</span><span class="p">))</span>
<span class="go">[0, 1, 2, 3, 4]</span>
</pre></div>
</div>
<p>The last number is 4 (not 5 as might be expected), but there are 5
elements in the list.</p>
<p>The <a class="reference external" href="http://docs.python.org/tutorial/controlflow.html#for-statements">for</a> executes the following indented statement once for every element in the <code class="docutils literal notranslate"><span class="pre">in</span></code> list:</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">'a'</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">,</span> <span class="s1">'c'</span><span class="p">]:</span>
<span class="gp">... </span> <span class="nb">print</span> <span class="n">i</span>
<span class="go">a</span>
<span class="go">b</span>
<span class="go">c</span>
</pre></div>
</div>
<p>Indentation is significant in Python! Normally indents are four spaces and the tab key will do the job. (In the above example, you may need to hit enter twice after the print statement, the second to terminate the indentation.)</p>
<p><a class="reference external" href="http://docs.python.org/tutorial/datastructures.html#more-on-lists">pop</a> returns one element from a list, and deletes it from the list. Using <code class="docutils literal notranslate"><span class="pre">0</span></code> pops off the first element, and <code class="docutils literal notranslate"><span class="pre">file.write()</span></code> writes a string to a file. <code class="docutils literal notranslate"><span class="pre">+</span></code> can be used to concatenate two strings together. Since <a class="reference external" href="https://docs.python.org/3/library/stdtypes.html#str.split" title="(in Python v3.13)"><code class="xref py py-meth docutils literal notranslate"><span class="pre">split()</span></code></a> removed the newlines, they need to be readded.</p>
<p>So this little block of code splits the data into a list on newlines and, repeating fifteen times, takes the first element of that list and writes it, with a newline, to the output. Now <code class="docutils literal notranslate"><span class="pre">data</span></code> contains only the actual lines of data.</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">oldline</span> <span class="o">=</span> <span class="kc">None</span>
<span class="gp">>>> </span><span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">data</span><span class="p">:</span>
<span class="gp">... </span> <span class="k">if</span> <span class="n">line</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="mi">2</span><span class="p">]</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">'19'</span><span class="p">,</span> <span class="s1">'20'</span><span class="p">,</span> <span class="s1">'2'</span><span class="p">]:</span>
<span class="gp">... </span> <span class="k">if</span> <span class="ow">not</span> <span class="n">oldline</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="gp">... </span> <span class="n">outfile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">oldline</span> <span class="o">+</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
<span class="gp">... </span> <span class="n">oldline</span> <span class="o">=</span> <span class="n">line</span>
<span class="gp">... </span> <span class="k">else</span><span class="p">:</span>
<span class="gp">... </span> <span class="n">oldline</span> <span class="o">+=</span> <span class="n">line</span>
<span class="gp">>>> </span><span class="n">outfile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">oldline</span> <span class="o">+</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
<span class="gp">>>> </span><span class="n">outfile</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">None</span></code> is a special Python value specifically indicating nothing;
it’s used here to mark the first time around the loop.</p>
<p><code class="docutils literal notranslate"><span class="pre">line[0:2]</span></code> gets the first two characters in the string <code class="docutils literal notranslate"><span class="pre">line</span></code>, and
the <code class="docutils literal notranslate"><span class="pre">in</span></code> operator compares the resulting string to see if it is
present in the following list. This will return <code class="docutils literal notranslate"><span class="pre">True</span></code> if the line
begins with <code class="docutils literal notranslate"><span class="pre">19</span></code> or <code class="docutils literal notranslate"><span class="pre">20</span></code>. The <a class="reference external" href="http://docs.python.org/tutorial/controlflow.html#if-statements">if</a>
statement executes the following indented block if the condition is
True. So, if this is True, the previous line probably ended properly
and it can be written out. First there is an additional check that
this isn’t the first time around the loop, and then the <em>previous</em>
line (which we know ended cleanly) is written out. The currently-read
line then becomes the new “previous” line.</p>
<p>The <code class="docutils literal notranslate"><span class="pre">2</span></code> is a special case: if the line is less than two characters
long, <code class="docutils literal notranslate"><span class="pre">line[0:2]</span></code> will return the entire line, and it so happens
that these cases always correspond to the previous line being whole.</p>
<p>If this test fails, everything under <code class="docutils literal notranslate"><span class="pre">else</span></code> is executed. Here the
assumption is that the previous line didn’t end cleanly and the
current line is actually a continuation of it, so the current line is
appended to the previous. <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">+=</span> <span class="pre">b</span></code> is a shortcut for <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">=</span> <span class="pre">a</span> <span class="pre">+</span> <span class="pre">b</span></code>.</p>
<p>Once the loop terminates, the last line is written out, and the file closed.</p>
</section>
</section>
<div class="clearer"></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="index.html">
<img class="logo" src="_static/logo.png" alt="Logo"/>
</a></p>
<div>
<h3><a href="index.html">Table of Contents</a></h3>
<ul>
<li><a class="reference internal" href="#">Paulikas and Blake revisited (Reeves et al. 2011)</a><ul>
<li><a class="reference internal" href="#setup">Setup</a></li>
<li><a class="reference internal" href="#obtaining-energetic-particle-data">Obtaining energetic particle data</a></li>
<li><a class="reference internal" href="#solar-wind-data-and-averaging">Solar Wind data and averaging</a></li>
<li><a class="reference internal" href="#making-figure-1">Making Figure 1</a></li>
<li><a class="reference internal" href="#appendix-fixing-the-esp-data-file">Appendix: Fixing the ESP data file</a></li>
</ul>
</li>
</ul>
</div>
<div>
<h4>Previous topic</h4>
<p class="topless"><a href="case_studies.html"
title="previous chapter">SpacePy Case Studies</a></p>
</div>
<div>
<h4>Next topic</h4>
<p class="topless"><a href="publications.html"
title="next chapter">Publication List</a></p>
</div>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
<li><a href="_sources/case_reeves_morley_friedel_2011.rst.txt"
rel="nofollow">Show Source</a></li>
</ul>
</div>
<search id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="right" >
<a href="publications.html" title="Publication List"
>next</a> |</li>
<li class="right" >
<a href="case_studies.html" title="SpacePy Case Studies"
>previous</a> |</li>
<li><a href="https://spacepy.github.io/"">homepage</a>| </li>
<li><a href="https://github.com/spacepy/spacepy">development</a>| </li>
<li><a href="search.html">search</a>| </li>
<li><a href="index.html">documentation </a> »</li>
<li class="nav-item nav-item-1"><a href="case_studies.html" >SpacePy Case Studies</a> »</li>
<li class="nav-item nav-item-this"><a href="">Paulikas and Blake revisited (Reeves et al. 2011)</a></li>
</ul>
</div>
<div class="footer" role="contentinfo">
© Copyright 2011-2024, The SpacePy Team.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 7.3.7.
</div>
</body>
</html>