moderne-visualizations-misc 0.71.2__py3-none-any.whl → 0.73.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@
2
2
  "cells": [
3
3
  {
4
4
  "cell_type": "code",
5
- "execution_count": 5,
5
+ "execution_count": 3,
6
6
  "metadata": {
7
7
  "tags": [
8
8
  "parameters"
@@ -15,1316 +15,10 @@
15
15
  },
16
16
  {
17
17
  "cell_type": "code",
18
- "execution_count": 6,
18
+ "execution_count": null,
19
19
  "metadata": {},
20
- "outputs": [
21
- {
22
- "data": {
23
- "application/vnd.plotly.v1+json": {
24
- "config": {
25
- "plotlyServerURL": "https://plot.ly"
26
- },
27
- "data": [
28
- {
29
- "alignmentgroup": "True",
30
- "customdata": [
31
- [
32
- 21.8,
33
- 52.9,
34
- 25.1,
35
- 0.3
36
- ],
37
- [
38
- 27,
39
- 55.7,
40
- 15.2,
41
- 2
42
- ],
43
- [
44
- 21.8,
45
- 27.3,
46
- 49.1,
47
- 1.8
48
- ],
49
- [
50
- 37.3,
51
- 31.4,
52
- 11.8,
53
- 19.6
54
- ]
55
- ],
56
- "hovertemplate": "<b>%{hovertext}</b><br><br>Severity=Critical<br>Type of version required to fix vulnerability=%{x}<br>value=%{y}<br>Critical %=%{customdata[0]}<br>High %=%{customdata[1]}<br>Moderate %=%{customdata[2]}<br>Low %=%{customdata[3]}<extra></extra>",
57
- "hovertext": [
58
- "Patch",
59
- "Minor",
60
- "Major",
61
- "No fixed version"
62
- ],
63
- "legendgroup": "Critical",
64
- "marker": {
65
- "color": "#FF5B5B",
66
- "pattern": {
67
- "shape": ""
68
- }
69
- },
70
- "name": "Critical",
71
- "offsetgroup": "Critical",
72
- "orientation": "v",
73
- "showlegend": true,
74
- "textposition": "auto",
75
- "type": "bar",
76
- "width": 0.33,
77
- "x": [
78
- "Patch",
79
- "Minor",
80
- "Major",
81
- "No fixed version"
82
- ],
83
- "xaxis": "x",
84
- "y": [
85
- 79,
86
- 66,
87
- 12,
88
- 19
89
- ],
90
- "yaxis": "y"
91
- },
92
- {
93
- "alignmentgroup": "True",
94
- "customdata": [
95
- [
96
- 21.8,
97
- 52.9,
98
- 25.1,
99
- 0.3
100
- ],
101
- [
102
- 27,
103
- 55.7,
104
- 15.2,
105
- 2
106
- ],
107
- [
108
- 21.8,
109
- 27.3,
110
- 49.1,
111
- 1.8
112
- ],
113
- [
114
- 37.3,
115
- 31.4,
116
- 11.8,
117
- 19.6
118
- ]
119
- ],
120
- "hovertemplate": "<b>%{hovertext}</b><br><br>Severity=High<br>Type of version required to fix vulnerability=%{x}<br>value=%{y}<br>Critical %=%{customdata[0]}<br>High %=%{customdata[1]}<br>Moderate %=%{customdata[2]}<br>Low %=%{customdata[3]}<extra></extra>",
121
- "hovertext": [
122
- "Patch",
123
- "Minor",
124
- "Major",
125
- "No fixed version"
126
- ],
127
- "legendgroup": "High",
128
- "marker": {
129
- "color": "#FABA49",
130
- "pattern": {
131
- "shape": ""
132
- }
133
- },
134
- "name": "High",
135
- "offsetgroup": "High",
136
- "orientation": "v",
137
- "showlegend": true,
138
- "textposition": "auto",
139
- "type": "bar",
140
- "width": 0.33,
141
- "x": [
142
- "Patch",
143
- "Minor",
144
- "Major",
145
- "No fixed version"
146
- ],
147
- "xaxis": "x",
148
- "y": [
149
- 192,
150
- 136,
151
- 15,
152
- 16
153
- ],
154
- "yaxis": "y"
155
- },
156
- {
157
- "alignmentgroup": "True",
158
- "customdata": [
159
- [
160
- 21.8,
161
- 52.9,
162
- 25.1,
163
- 0.3
164
- ],
165
- [
166
- 27,
167
- 55.7,
168
- 15.2,
169
- 2
170
- ],
171
- [
172
- 21.8,
173
- 27.3,
174
- 49.1,
175
- 1.8
176
- ],
177
- [
178
- 37.3,
179
- 31.4,
180
- 11.8,
181
- 19.6
182
- ]
183
- ],
184
- "hovertemplate": "<b>%{hovertext}</b><br><br>Severity=Moderate<br>Type of version required to fix vulnerability=%{x}<br>value=%{y}<br>Critical %=%{customdata[0]}<br>High %=%{customdata[1]}<br>Moderate %=%{customdata[2]}<br>Low %=%{customdata[3]}<extra></extra>",
185
- "hovertext": [
186
- "Patch",
187
- "Minor",
188
- "Major",
189
- "No fixed version"
190
- ],
191
- "legendgroup": "Moderate",
192
- "marker": {
193
- "color": "#FEE968",
194
- "pattern": {
195
- "shape": ""
196
- }
197
- },
198
- "name": "Moderate",
199
- "offsetgroup": "Moderate",
200
- "orientation": "v",
201
- "showlegend": true,
202
- "textposition": "auto",
203
- "type": "bar",
204
- "width": 0.33,
205
- "x": [
206
- "Patch",
207
- "Minor",
208
- "Major",
209
- "No fixed version"
210
- ],
211
- "xaxis": "x",
212
- "y": [
213
- 91,
214
- 37,
215
- 27,
216
- 6
217
- ],
218
- "yaxis": "y"
219
- },
220
- {
221
- "alignmentgroup": "True",
222
- "customdata": [
223
- [
224
- 21.8,
225
- 52.9,
226
- 25.1,
227
- 0.3
228
- ],
229
- [
230
- 27,
231
- 55.7,
232
- 15.2,
233
- 2
234
- ],
235
- [
236
- 21.8,
237
- 27.3,
238
- 49.1,
239
- 1.8
240
- ],
241
- [
242
- 37.3,
243
- 31.4,
244
- 11.8,
245
- 19.6
246
- ]
247
- ],
248
- "hovertemplate": "<b>%{hovertext}</b><br><br>Severity=Low<br>Type of version required to fix vulnerability=%{x}<br>value=%{y}<br>Critical %=%{customdata[0]}<br>High %=%{customdata[1]}<br>Moderate %=%{customdata[2]}<br>Low %=%{customdata[3]}<extra></extra>",
249
- "hovertext": [
250
- "Patch",
251
- "Minor",
252
- "Major",
253
- "No fixed version"
254
- ],
255
- "legendgroup": "Low",
256
- "marker": {
257
- "color": "#52BBA0",
258
- "pattern": {
259
- "shape": ""
260
- }
261
- },
262
- "name": "Low",
263
- "offsetgroup": "Low",
264
- "orientation": "v",
265
- "showlegend": true,
266
- "textposition": "auto",
267
- "type": "bar",
268
- "width": 0.33,
269
- "x": [
270
- "Patch",
271
- "Minor",
272
- "Major",
273
- "No fixed version"
274
- ],
275
- "xaxis": "x",
276
- "y": [
277
- 1,
278
- 5,
279
- 1,
280
- 10
281
- ],
282
- "yaxis": "y"
283
- }
284
- ],
285
- "layout": {
286
- "barmode": "stack",
287
- "legend": {
288
- "title": {
289
- "text": "Severity"
290
- },
291
- "tracegroupgap": 0
292
- },
293
- "margin": {
294
- "b": 0,
295
- "l": 0,
296
- "r": 0,
297
- "t": 30
298
- },
299
- "template": {
300
- "data": {
301
- "bar": [
302
- {
303
- "error_x": {
304
- "color": "#2a3f5f"
305
- },
306
- "error_y": {
307
- "color": "#2a3f5f"
308
- },
309
- "marker": {
310
- "line": {
311
- "color": "#E5ECF6",
312
- "width": 0.5
313
- },
314
- "pattern": {
315
- "fillmode": "overlay",
316
- "size": 10,
317
- "solidity": 0.2
318
- }
319
- },
320
- "type": "bar"
321
- }
322
- ],
323
- "barpolar": [
324
- {
325
- "marker": {
326
- "line": {
327
- "color": "#E5ECF6",
328
- "width": 0.5
329
- },
330
- "pattern": {
331
- "fillmode": "overlay",
332
- "size": 10,
333
- "solidity": 0.2
334
- }
335
- },
336
- "type": "barpolar"
337
- }
338
- ],
339
- "carpet": [
340
- {
341
- "aaxis": {
342
- "endlinecolor": "#2a3f5f",
343
- "gridcolor": "white",
344
- "linecolor": "white",
345
- "minorgridcolor": "white",
346
- "startlinecolor": "#2a3f5f"
347
- },
348
- "baxis": {
349
- "endlinecolor": "#2a3f5f",
350
- "gridcolor": "white",
351
- "linecolor": "white",
352
- "minorgridcolor": "white",
353
- "startlinecolor": "#2a3f5f"
354
- },
355
- "type": "carpet"
356
- }
357
- ],
358
- "choropleth": [
359
- {
360
- "colorbar": {
361
- "outlinewidth": 0,
362
- "ticks": ""
363
- },
364
- "type": "choropleth"
365
- }
366
- ],
367
- "contour": [
368
- {
369
- "colorbar": {
370
- "outlinewidth": 0,
371
- "ticks": ""
372
- },
373
- "colorscale": [
374
- [
375
- 0,
376
- "#0d0887"
377
- ],
378
- [
379
- 0.1111111111111111,
380
- "#46039f"
381
- ],
382
- [
383
- 0.2222222222222222,
384
- "#7201a8"
385
- ],
386
- [
387
- 0.3333333333333333,
388
- "#9c179e"
389
- ],
390
- [
391
- 0.4444444444444444,
392
- "#bd3786"
393
- ],
394
- [
395
- 0.5555555555555556,
396
- "#d8576b"
397
- ],
398
- [
399
- 0.6666666666666666,
400
- "#ed7953"
401
- ],
402
- [
403
- 0.7777777777777778,
404
- "#fb9f3a"
405
- ],
406
- [
407
- 0.8888888888888888,
408
- "#fdca26"
409
- ],
410
- [
411
- 1,
412
- "#f0f921"
413
- ]
414
- ],
415
- "type": "contour"
416
- }
417
- ],
418
- "contourcarpet": [
419
- {
420
- "colorbar": {
421
- "outlinewidth": 0,
422
- "ticks": ""
423
- },
424
- "type": "contourcarpet"
425
- }
426
- ],
427
- "heatmap": [
428
- {
429
- "colorbar": {
430
- "outlinewidth": 0,
431
- "ticks": ""
432
- },
433
- "colorscale": [
434
- [
435
- 0,
436
- "#0d0887"
437
- ],
438
- [
439
- 0.1111111111111111,
440
- "#46039f"
441
- ],
442
- [
443
- 0.2222222222222222,
444
- "#7201a8"
445
- ],
446
- [
447
- 0.3333333333333333,
448
- "#9c179e"
449
- ],
450
- [
451
- 0.4444444444444444,
452
- "#bd3786"
453
- ],
454
- [
455
- 0.5555555555555556,
456
- "#d8576b"
457
- ],
458
- [
459
- 0.6666666666666666,
460
- "#ed7953"
461
- ],
462
- [
463
- 0.7777777777777778,
464
- "#fb9f3a"
465
- ],
466
- [
467
- 0.8888888888888888,
468
- "#fdca26"
469
- ],
470
- [
471
- 1,
472
- "#f0f921"
473
- ]
474
- ],
475
- "type": "heatmap"
476
- }
477
- ],
478
- "heatmapgl": [
479
- {
480
- "colorbar": {
481
- "outlinewidth": 0,
482
- "ticks": ""
483
- },
484
- "colorscale": [
485
- [
486
- 0,
487
- "#0d0887"
488
- ],
489
- [
490
- 0.1111111111111111,
491
- "#46039f"
492
- ],
493
- [
494
- 0.2222222222222222,
495
- "#7201a8"
496
- ],
497
- [
498
- 0.3333333333333333,
499
- "#9c179e"
500
- ],
501
- [
502
- 0.4444444444444444,
503
- "#bd3786"
504
- ],
505
- [
506
- 0.5555555555555556,
507
- "#d8576b"
508
- ],
509
- [
510
- 0.6666666666666666,
511
- "#ed7953"
512
- ],
513
- [
514
- 0.7777777777777778,
515
- "#fb9f3a"
516
- ],
517
- [
518
- 0.8888888888888888,
519
- "#fdca26"
520
- ],
521
- [
522
- 1,
523
- "#f0f921"
524
- ]
525
- ],
526
- "type": "heatmapgl"
527
- }
528
- ],
529
- "histogram": [
530
- {
531
- "marker": {
532
- "pattern": {
533
- "fillmode": "overlay",
534
- "size": 10,
535
- "solidity": 0.2
536
- }
537
- },
538
- "type": "histogram"
539
- }
540
- ],
541
- "histogram2d": [
542
- {
543
- "colorbar": {
544
- "outlinewidth": 0,
545
- "ticks": ""
546
- },
547
- "colorscale": [
548
- [
549
- 0,
550
- "#0d0887"
551
- ],
552
- [
553
- 0.1111111111111111,
554
- "#46039f"
555
- ],
556
- [
557
- 0.2222222222222222,
558
- "#7201a8"
559
- ],
560
- [
561
- 0.3333333333333333,
562
- "#9c179e"
563
- ],
564
- [
565
- 0.4444444444444444,
566
- "#bd3786"
567
- ],
568
- [
569
- 0.5555555555555556,
570
- "#d8576b"
571
- ],
572
- [
573
- 0.6666666666666666,
574
- "#ed7953"
575
- ],
576
- [
577
- 0.7777777777777778,
578
- "#fb9f3a"
579
- ],
580
- [
581
- 0.8888888888888888,
582
- "#fdca26"
583
- ],
584
- [
585
- 1,
586
- "#f0f921"
587
- ]
588
- ],
589
- "type": "histogram2d"
590
- }
591
- ],
592
- "histogram2dcontour": [
593
- {
594
- "colorbar": {
595
- "outlinewidth": 0,
596
- "ticks": ""
597
- },
598
- "colorscale": [
599
- [
600
- 0,
601
- "#0d0887"
602
- ],
603
- [
604
- 0.1111111111111111,
605
- "#46039f"
606
- ],
607
- [
608
- 0.2222222222222222,
609
- "#7201a8"
610
- ],
611
- [
612
- 0.3333333333333333,
613
- "#9c179e"
614
- ],
615
- [
616
- 0.4444444444444444,
617
- "#bd3786"
618
- ],
619
- [
620
- 0.5555555555555556,
621
- "#d8576b"
622
- ],
623
- [
624
- 0.6666666666666666,
625
- "#ed7953"
626
- ],
627
- [
628
- 0.7777777777777778,
629
- "#fb9f3a"
630
- ],
631
- [
632
- 0.8888888888888888,
633
- "#fdca26"
634
- ],
635
- [
636
- 1,
637
- "#f0f921"
638
- ]
639
- ],
640
- "type": "histogram2dcontour"
641
- }
642
- ],
643
- "mesh3d": [
644
- {
645
- "colorbar": {
646
- "outlinewidth": 0,
647
- "ticks": ""
648
- },
649
- "type": "mesh3d"
650
- }
651
- ],
652
- "parcoords": [
653
- {
654
- "line": {
655
- "colorbar": {
656
- "outlinewidth": 0,
657
- "ticks": ""
658
- }
659
- },
660
- "type": "parcoords"
661
- }
662
- ],
663
- "pie": [
664
- {
665
- "automargin": true,
666
- "type": "pie"
667
- }
668
- ],
669
- "scatter": [
670
- {
671
- "fillpattern": {
672
- "fillmode": "overlay",
673
- "size": 10,
674
- "solidity": 0.2
675
- },
676
- "type": "scatter"
677
- }
678
- ],
679
- "scatter3d": [
680
- {
681
- "line": {
682
- "colorbar": {
683
- "outlinewidth": 0,
684
- "ticks": ""
685
- }
686
- },
687
- "marker": {
688
- "colorbar": {
689
- "outlinewidth": 0,
690
- "ticks": ""
691
- }
692
- },
693
- "type": "scatter3d"
694
- }
695
- ],
696
- "scattercarpet": [
697
- {
698
- "marker": {
699
- "colorbar": {
700
- "outlinewidth": 0,
701
- "ticks": ""
702
- }
703
- },
704
- "type": "scattercarpet"
705
- }
706
- ],
707
- "scattergeo": [
708
- {
709
- "marker": {
710
- "colorbar": {
711
- "outlinewidth": 0,
712
- "ticks": ""
713
- }
714
- },
715
- "type": "scattergeo"
716
- }
717
- ],
718
- "scattergl": [
719
- {
720
- "marker": {
721
- "colorbar": {
722
- "outlinewidth": 0,
723
- "ticks": ""
724
- }
725
- },
726
- "type": "scattergl"
727
- }
728
- ],
729
- "scattermapbox": [
730
- {
731
- "marker": {
732
- "colorbar": {
733
- "outlinewidth": 0,
734
- "ticks": ""
735
- }
736
- },
737
- "type": "scattermapbox"
738
- }
739
- ],
740
- "scatterpolar": [
741
- {
742
- "marker": {
743
- "colorbar": {
744
- "outlinewidth": 0,
745
- "ticks": ""
746
- }
747
- },
748
- "type": "scatterpolar"
749
- }
750
- ],
751
- "scatterpolargl": [
752
- {
753
- "marker": {
754
- "colorbar": {
755
- "outlinewidth": 0,
756
- "ticks": ""
757
- }
758
- },
759
- "type": "scatterpolargl"
760
- }
761
- ],
762
- "scatterternary": [
763
- {
764
- "marker": {
765
- "colorbar": {
766
- "outlinewidth": 0,
767
- "ticks": ""
768
- }
769
- },
770
- "type": "scatterternary"
771
- }
772
- ],
773
- "surface": [
774
- {
775
- "colorbar": {
776
- "outlinewidth": 0,
777
- "ticks": ""
778
- },
779
- "colorscale": [
780
- [
781
- 0,
782
- "#0d0887"
783
- ],
784
- [
785
- 0.1111111111111111,
786
- "#46039f"
787
- ],
788
- [
789
- 0.2222222222222222,
790
- "#7201a8"
791
- ],
792
- [
793
- 0.3333333333333333,
794
- "#9c179e"
795
- ],
796
- [
797
- 0.4444444444444444,
798
- "#bd3786"
799
- ],
800
- [
801
- 0.5555555555555556,
802
- "#d8576b"
803
- ],
804
- [
805
- 0.6666666666666666,
806
- "#ed7953"
807
- ],
808
- [
809
- 0.7777777777777778,
810
- "#fb9f3a"
811
- ],
812
- [
813
- 0.8888888888888888,
814
- "#fdca26"
815
- ],
816
- [
817
- 1,
818
- "#f0f921"
819
- ]
820
- ],
821
- "type": "surface"
822
- }
823
- ],
824
- "table": [
825
- {
826
- "cells": {
827
- "fill": {
828
- "color": "#EBF0F8"
829
- },
830
- "line": {
831
- "color": "white"
832
- }
833
- },
834
- "header": {
835
- "fill": {
836
- "color": "#C8D4E3"
837
- },
838
- "line": {
839
- "color": "white"
840
- }
841
- },
842
- "type": "table"
843
- }
844
- ]
845
- },
846
- "layout": {
847
- "annotationdefaults": {
848
- "arrowcolor": "#2a3f5f",
849
- "arrowhead": 0,
850
- "arrowwidth": 1
851
- },
852
- "autotypenumbers": "strict",
853
- "coloraxis": {
854
- "colorbar": {
855
- "outlinewidth": 0,
856
- "ticks": ""
857
- }
858
- },
859
- "colorscale": {
860
- "diverging": [
861
- [
862
- 0,
863
- "#8e0152"
864
- ],
865
- [
866
- 0.1,
867
- "#c51b7d"
868
- ],
869
- [
870
- 0.2,
871
- "#de77ae"
872
- ],
873
- [
874
- 0.3,
875
- "#f1b6da"
876
- ],
877
- [
878
- 0.4,
879
- "#fde0ef"
880
- ],
881
- [
882
- 0.5,
883
- "#f7f7f7"
884
- ],
885
- [
886
- 0.6,
887
- "#e6f5d0"
888
- ],
889
- [
890
- 0.7,
891
- "#b8e186"
892
- ],
893
- [
894
- 0.8,
895
- "#7fbc41"
896
- ],
897
- [
898
- 0.9,
899
- "#4d9221"
900
- ],
901
- [
902
- 1,
903
- "#276419"
904
- ]
905
- ],
906
- "sequential": [
907
- [
908
- 0,
909
- "#0d0887"
910
- ],
911
- [
912
- 0.1111111111111111,
913
- "#46039f"
914
- ],
915
- [
916
- 0.2222222222222222,
917
- "#7201a8"
918
- ],
919
- [
920
- 0.3333333333333333,
921
- "#9c179e"
922
- ],
923
- [
924
- 0.4444444444444444,
925
- "#bd3786"
926
- ],
927
- [
928
- 0.5555555555555556,
929
- "#d8576b"
930
- ],
931
- [
932
- 0.6666666666666666,
933
- "#ed7953"
934
- ],
935
- [
936
- 0.7777777777777778,
937
- "#fb9f3a"
938
- ],
939
- [
940
- 0.8888888888888888,
941
- "#fdca26"
942
- ],
943
- [
944
- 1,
945
- "#f0f921"
946
- ]
947
- ],
948
- "sequentialminus": [
949
- [
950
- 0,
951
- "#0d0887"
952
- ],
953
- [
954
- 0.1111111111111111,
955
- "#46039f"
956
- ],
957
- [
958
- 0.2222222222222222,
959
- "#7201a8"
960
- ],
961
- [
962
- 0.3333333333333333,
963
- "#9c179e"
964
- ],
965
- [
966
- 0.4444444444444444,
967
- "#bd3786"
968
- ],
969
- [
970
- 0.5555555555555556,
971
- "#d8576b"
972
- ],
973
- [
974
- 0.6666666666666666,
975
- "#ed7953"
976
- ],
977
- [
978
- 0.7777777777777778,
979
- "#fb9f3a"
980
- ],
981
- [
982
- 0.8888888888888888,
983
- "#fdca26"
984
- ],
985
- [
986
- 1,
987
- "#f0f921"
988
- ]
989
- ]
990
- },
991
- "colorway": [
992
- "#636efa",
993
- "#EF553B",
994
- "#00cc96",
995
- "#ab63fa",
996
- "#FFA15A",
997
- "#19d3f3",
998
- "#FF6692",
999
- "#B6E880",
1000
- "#FF97FF",
1001
- "#FECB52"
1002
- ],
1003
- "font": {
1004
- "color": "#2a3f5f"
1005
- },
1006
- "geo": {
1007
- "bgcolor": "white",
1008
- "lakecolor": "white",
1009
- "landcolor": "#E5ECF6",
1010
- "showlakes": true,
1011
- "showland": true,
1012
- "subunitcolor": "white"
1013
- },
1014
- "hoverlabel": {
1015
- "align": "left"
1016
- },
1017
- "hovermode": "closest",
1018
- "mapbox": {
1019
- "style": "light"
1020
- },
1021
- "paper_bgcolor": "white",
1022
- "plot_bgcolor": "#E5ECF6",
1023
- "polar": {
1024
- "angularaxis": {
1025
- "gridcolor": "white",
1026
- "linecolor": "white",
1027
- "ticks": ""
1028
- },
1029
- "bgcolor": "#E5ECF6",
1030
- "radialaxis": {
1031
- "gridcolor": "white",
1032
- "linecolor": "white",
1033
- "ticks": ""
1034
- }
1035
- },
1036
- "scene": {
1037
- "xaxis": {
1038
- "backgroundcolor": "#E5ECF6",
1039
- "gridcolor": "white",
1040
- "gridwidth": 2,
1041
- "linecolor": "white",
1042
- "showbackground": true,
1043
- "ticks": "",
1044
- "zerolinecolor": "white"
1045
- },
1046
- "yaxis": {
1047
- "backgroundcolor": "#E5ECF6",
1048
- "gridcolor": "white",
1049
- "gridwidth": 2,
1050
- "linecolor": "white",
1051
- "showbackground": true,
1052
- "ticks": "",
1053
- "zerolinecolor": "white"
1054
- },
1055
- "zaxis": {
1056
- "backgroundcolor": "#E5ECF6",
1057
- "gridcolor": "white",
1058
- "gridwidth": 2,
1059
- "linecolor": "white",
1060
- "showbackground": true,
1061
- "ticks": "",
1062
- "zerolinecolor": "white"
1063
- }
1064
- },
1065
- "shapedefaults": {
1066
- "line": {
1067
- "color": "#2a3f5f"
1068
- }
1069
- },
1070
- "ternary": {
1071
- "aaxis": {
1072
- "gridcolor": "white",
1073
- "linecolor": "white",
1074
- "ticks": ""
1075
- },
1076
- "baxis": {
1077
- "gridcolor": "white",
1078
- "linecolor": "white",
1079
- "ticks": ""
1080
- },
1081
- "bgcolor": "#E5ECF6",
1082
- "caxis": {
1083
- "gridcolor": "white",
1084
- "linecolor": "white",
1085
- "ticks": ""
1086
- }
1087
- },
1088
- "title": {
1089
- "x": 0.05
1090
- },
1091
- "xaxis": {
1092
- "automargin": true,
1093
- "gridcolor": "white",
1094
- "linecolor": "white",
1095
- "ticks": "",
1096
- "title": {
1097
- "standoff": 15
1098
- },
1099
- "zerolinecolor": "white",
1100
- "zerolinewidth": 2
1101
- },
1102
- "yaxis": {
1103
- "automargin": true,
1104
- "gridcolor": "white",
1105
- "linecolor": "white",
1106
- "ticks": "",
1107
- "title": {
1108
- "standoff": 15
1109
- },
1110
- "zerolinecolor": "white",
1111
- "zerolinewidth": 2
1112
- }
1113
- }
1114
- },
1115
- "xaxis": {
1116
- "anchor": "y",
1117
- "domain": [
1118
- 0,
1119
- 1
1120
- ],
1121
- "title": {
1122
- "text": "Type of version required to fix vulnerability"
1123
- }
1124
- },
1125
- "yaxis": {
1126
- "anchor": "x",
1127
- "domain": [
1128
- 0,
1129
- 1
1130
- ],
1131
- "title": {
1132
- "text": "Vulnerability count"
1133
- }
1134
- }
1135
- }
1136
- }
1137
- },
1138
- "metadata": {},
1139
- "output_type": "display_data"
1140
- }
1141
- ],
1142
- "source": [
1143
- "import pandas as pd\n",
1144
- "import warnings\n",
1145
- "import plotly.express as px\n",
1146
- "import code_data_science.data_table as dt\n",
1147
- "\n",
1148
- "warnings.simplefilter(\"ignore\")\n",
1149
- "\n",
1150
- "df = dt.read_csv(\"../samples/dependency_vulnerabilities.csv\")\n",
1151
- "\n",
1152
- "df[\"repositoryWithBranch\"] = df[\"repositoryPath\"] + \"/\" + df[\"repositoryBranch\"]\n",
1153
- "\n",
1154
- "# Filter the data frame to only include rows where repositoryWithBranch contain\n",
1155
- "# a term in the repository_filter (case insensitive)\n",
1156
- "if len(repository_filter) > 0:\n",
1157
- " df = df[\n",
1158
- " df[\"repositoryWithBranch\"].str.contains(\"|\".join(repository_filter), case=False)\n",
1159
- " ]\n",
1160
- "\n",
1161
- "\n",
1162
- "def create_bar_plot(df_plot):\n",
1163
- " if df_plot is None:\n",
1164
- " df_plot = pd.DataFrame(\n",
1165
- " {\n",
1166
- " \"Type of version required to fix vulnerability\": [\n",
1167
- " \"Patch\",\n",
1168
- " \"Minor\",\n",
1169
- " \"Major\",\n",
1170
- " \"No fixed version\",\n",
1171
- " ],\n",
1172
- " \"Low\": 0,\n",
1173
- " \"Moderate\": 0,\n",
1174
- " \"High\": 0,\n",
1175
- " \"Critical\": 0,\n",
1176
- " \"Critical %\": 0,\n",
1177
- " \"High %\": 0,\n",
1178
- " \"Moderate %\": 0,\n",
1179
- " \"Low %\": 0,\n",
1180
- " \"Total\": 0,\n",
1181
- " }\n",
1182
- " )\n",
1183
- "\n",
1184
- " fig = px.bar(\n",
1185
- " df_plot,\n",
1186
- " x=\"Type of version required to fix vulnerability\",\n",
1187
- " y=[\"Critical\", \"High\", \"Moderate\", \"Low\"],\n",
1188
- " color_discrete_map={\n",
1189
- " \"Low\": \"#52BBA0\",\n",
1190
- " \"Moderate\": \"#FEE968\",\n",
1191
- " \"High\": \"#FABA49\",\n",
1192
- " \"Critical\": \"#FF5B5B\",\n",
1193
- " },\n",
1194
- " barmode=\"stack\",\n",
1195
- " hover_name=\"Type of version required to fix vulnerability\",\n",
1196
- " hover_data={\n",
1197
- " \"Critical %\": True,\n",
1198
- " \"High %\": True,\n",
1199
- " \"Moderate %\": True,\n",
1200
- " \"Low %\": True,\n",
1201
- " },\n",
1202
- " labels={\"variable\": \"Severity\"},\n",
1203
- " )\n",
1204
- "\n",
1205
- " # Set the axis labels and title\n",
1206
- " fig.update_layout(\n",
1207
- " xaxis={\"title\": \"Type of version required to fix vulnerability\"},\n",
1208
- " yaxis={\"title\": \"Vulnerability count\"},\n",
1209
- " margin=dict(l=0, r=0, t=30, b=0),\n",
1210
- " )\n",
1211
- " return fig\n",
1212
- "\n",
1213
- "\n",
1214
- "# Exit early if there are no stack traces and render a plot with a message\n",
1215
- "if len(df) == 0:\n",
1216
- " fig = create_bar_plot(None)\n",
1217
- " fig.update_yaxes(range=[0, 10])\n",
1218
- " fig.show(render=\"plotly_mimetype\")\n",
1219
- "else:\n",
1220
- "\n",
1221
- " def get_semver_fix(version, fixed_version):\n",
1222
- " \"\"\"\n",
1223
- " looks at current version and fixed version and determines if the fix is a major, minor, patch version, or no fix\n",
1224
- " \"\"\"\n",
1225
- " version_components = version.split(\".\")\n",
1226
- " fixed_components = fixed_version.split(\".\")\n",
1227
- "\n",
1228
- " # if fixed version is empty, return \"No fixed version\"\n",
1229
- " if fixed_version == \"\":\n",
1230
- " return \"No fixed version\"\n",
1231
- "\n",
1232
- " if len(version_components) < 3:\n",
1233
- " # fill in the missing version components with 0\n",
1234
- " for i in range(3 - len(version_components)):\n",
1235
- " version_components.append(\"0\")\n",
1236
- " if len(fixed_components) < 3:\n",
1237
- " # fill in the missing version components with 0\n",
1238
- " for i in range(3 - len(fixed_components)):\n",
1239
- " fixed_components.append(\"0\")\n",
1240
- "\n",
1241
- " elif version_components[0] != fixed_components[0]:\n",
1242
- " return \"Major\"\n",
1243
- " elif version_components[1] != fixed_components[1]:\n",
1244
- " return \"Minor\"\n",
1245
- " elif version_components[2] != fixed_components[2]:\n",
1246
- " return \"Patch\"\n",
1247
- " else:\n",
1248
- " return \"Unknown\"\n",
1249
- "\n",
1250
- " # drop unnecessary columns\n",
1251
- " df = df.drop(\n",
1252
- " columns=[\n",
1253
- " \"repositoryOrigin\",\n",
1254
- " \"repositoryPath\",\n",
1255
- " \"repositoryBranch\",\n",
1256
- " \"repositoryWithBranch\",\n",
1257
- " \"cve\",\n",
1258
- " \"groupId\",\n",
1259
- " \"artifactId\",\n",
1260
- " \"summary\",\n",
1261
- " \"depth\",\n",
1262
- " ]\n",
1263
- " )\n",
1264
- "\n",
1265
- " # fill NaN values with empty string\n",
1266
- " df[\"fixedVersion\"] = df[\"fixedVersion\"].fillna(\"\")\n",
1267
- " df[\"version\"] = df[\"version\"].fillna(\"\")\n",
1268
- " # make sure version and fixedVersion is a string\n",
1269
- " df[\"fixedVersion\"] = df[\"fixedVersion\"].astype(str)\n",
1270
- " df[\"version\"] = df[\"version\"].astype(str)\n",
1271
- "\n",
1272
- " # add column 'semverFix' to dataframe\n",
1273
- " df[\"semverFix\"] = df.apply(\n",
1274
- " lambda x: get_semver_fix(x[\"version\"], x[\"fixedVersion\"]), axis=1\n",
1275
- " )\n",
1276
- " # count the occurrences of each semver fix\n",
1277
- " semverFix_counts = df[\"semverFix\"].value_counts()\n",
1278
- "\n",
1279
- " # sort the semver fixes in desired order\n",
1280
- " desired_order = [\"Patch\", \"Minor\", \"Major\", \"No fixed version\"]\n",
1281
- " semverFix_counts = semverFix_counts.reindex(desired_order)\n",
1282
- "\n",
1283
- " # count the number severity levels for each semver fix\n",
1284
- " critical_count = df[df[\"severity\"] == \"CRITICAL\"][\"semverFix\"].value_counts()\n",
1285
- " critical_count = critical_count.reindex(desired_order)\n",
1286
- "\n",
1287
- " high_count = df[df[\"severity\"] == \"HIGH\"][\"semverFix\"].value_counts()\n",
1288
- " high_count = high_count.reindex(desired_order)\n",
1289
- "\n",
1290
- " moderate_count = df[df[\"severity\"] == \"MODERATE\"][\"semverFix\"].value_counts()\n",
1291
- " moderate_count = moderate_count.reindex(desired_order)\n",
1292
- "\n",
1293
- " low_count = df[df[\"severity\"] == \"LOW\"][\"semverFix\"].value_counts()\n",
1294
- " low_count = low_count.reindex(desired_order)\n",
1295
- "\n",
1296
- " # Create a DataFrame with the data\n",
1297
- " df_plot = pd.DataFrame(\n",
1298
- " {\n",
1299
- " \"Type of version required to fix vulnerability\": semverFix_counts.index,\n",
1300
- " \"Low\": low_count,\n",
1301
- " \"Moderate\": moderate_count,\n",
1302
- " \"High\": high_count,\n",
1303
- " \"Critical\": critical_count,\n",
1304
- " }\n",
1305
- " )\n",
1306
- "\n",
1307
- " # Calculate the total count for each bar\n",
1308
- " df_plot[\"Total\"] = df_plot[[\"Critical\", \"High\", \"Moderate\", \"Low\"]].sum(axis=1)\n",
1309
- "\n",
1310
- " # Calculate the percentage of the total for each severity level\n",
1311
- " df_plot[\"Critical %\"] = (\n",
1312
- " (df_plot[\"Critical\"] / df_plot[\"Total\"] * 100).fillna(0).round(1)\n",
1313
- " )\n",
1314
- " df_plot[\"High %\"] = (df_plot[\"High\"] / df_plot[\"Total\"] * 100).fillna(0).round(1)\n",
1315
- " df_plot[\"Moderate %\"] = (\n",
1316
- " (df_plot[\"Moderate\"] / df_plot[\"Total\"] * 100).fillna(0).round(1)\n",
1317
- " )\n",
1318
- " df_plot[\"Low %\"] = (df_plot[\"Low\"] / df_plot[\"Total\"] * 100).fillna(0).round(1)\n",
1319
- "\n",
1320
- " fig = create_bar_plot(df_plot)\n",
1321
- "\n",
1322
- " # Set the y-axis range\n",
1323
- " fig.update_traces(width=0.33, textposition=\"auto\")\n",
1324
- "\n",
1325
- " # Show the figure\n",
1326
- " fig.show(render=\"plotly_mimetype\")"
1327
- ]
20
+ "outputs": [],
21
+ "source": "import pandas as pd\nimport warnings\nimport plotly.graph_objects as go\nimport code_data_science.data_table as dt\n\nwarnings.simplefilter(\"ignore\")\n\ndf = dt.read_csv(\"../samples/dependency_vulnerabilities.csv\")\n\ndf[\"repositoryWithBranch\"] = df[\"repositoryPath\"] + \"/\" + df[\"repositoryBranch\"]\n\n# Filter the data frame to only include rows where repositoryWithBranch contain\n# a term in the repository_filter (case insensitive)\nif len(repository_filter) > 0:\n df = df[\n df[\"repositoryWithBranch\"].str.contains(\"|\".join(repository_filter), case=False)\n ]\n\n\ndef create_bar_plot(df_direct, df_transitive):\n if df_direct is None or df_transitive is None:\n # Create empty dataframes with the correct structure\n fix_types = [\"Patch\", \"Minor\", \"Major\", \"No fixed version\"]\n df_direct = pd.DataFrame({\n \"Type\": fix_types,\n \"Low\": [0] * 4,\n \"Moderate\": [0] * 4,\n \"High\": [0] * 4,\n \"Critical\": [0] * 4,\n })\n df_transitive = pd.DataFrame({\n \"Type\": fix_types,\n \"Low\": [0] * 4,\n \"Moderate\": [0] * 4,\n \"High\": [0] * 4,\n \"Critical\": [0] * 4,\n })\n\n fig = go.Figure()\n \n # Define colors for severity levels\n colors = {\n \"Critical\": \"#FF5B5B\",\n \"High\": \"#FABA49\",\n \"Moderate\": \"#FEE968\",\n \"Low\": \"#52BBA0\"\n }\n \n # Calculate totals for percentage calculations\n df_direct[\"Total\"] = df_direct[[\"Critical\", \"High\", \"Moderate\", \"Low\"]].sum(axis=1)\n df_transitive[\"Total\"] = df_transitive[[\"Critical\", \"High\", \"Moderate\", \"Low\"]].sum(axis=1)\n grand_total = df_direct[\"Total\"].sum() + df_transitive[\"Total\"].sum()\n \n # Add traces for direct dependencies\n for i, severity in enumerate([\"Critical\", \"High\", \"Moderate\", \"Low\"]):\n # Calculate percentages for hover\n percentages_direct = []\n for idx in range(len(df_direct)):\n count = df_direct.iloc[idx][severity]\n total_in_category = df_direct.iloc[idx][\"Total\"] + df_transitive.iloc[idx][\"Total\"]\n pct_of_category = (count / total_in_category * 100) if total_in_category > 0 else 0\n pct_of_all = (count / grand_total * 100) if grand_total > 0 else 0\n percentages_direct.append({\n \"category_pct\": round(pct_of_category, 1),\n \"total_pct\": round(pct_of_all, 1)\n })\n \n fig.add_trace(go.Bar(\n name=severity,\n x=df_direct[\"Type\"],\n y=df_direct[severity],\n marker_color=colors[severity],\n legendgroup=severity,\n offsetgroup=\"direct\",\n showlegend=True,\n customdata=percentages_direct,\n hovertemplate=(\n '<b>%{x}</b><br>' +\n f'{severity} (Direct): %{{y}}<br>' +\n 'Percent of %{x}: %{customdata.category_pct}%<br>' +\n 'Percent of all: %{customdata.total_pct}%' +\n '<extra></extra>'\n )\n ))\n \n # Add traces for transitive dependencies\n for i, severity in enumerate([\"Critical\", \"High\", \"Moderate\", \"Low\"]):\n # Calculate percentages for hover\n percentages_transitive = []\n for idx in range(len(df_transitive)):\n count = df_transitive.iloc[idx][severity]\n total_in_category = df_direct.iloc[idx][\"Total\"] + df_transitive.iloc[idx][\"Total\"]\n pct_of_category = (count / total_in_category * 100) if total_in_category > 0 else 0\n pct_of_all = (count / grand_total * 100) if grand_total > 0 else 0\n percentages_transitive.append({\n \"category_pct\": round(pct_of_category, 1),\n \"total_pct\": round(pct_of_all, 1)\n })\n \n fig.add_trace(go.Bar(\n name=f'{severity} ', # Add space to make it different from direct\n x=df_transitive[\"Type\"],\n y=df_transitive[severity],\n marker_color=colors[severity],\n marker_pattern_shape=\"/\",\n legendgroup=severity,\n offsetgroup=\"transitive\",\n showlegend=False, # Hide from legend since we'll use annotations\n customdata=percentages_transitive,\n hovertemplate=(\n '<b>%{x}</b><br>' +\n f'{severity} (Transitive): %{{y}}<br>' +\n 'Percent of %{x}: %{customdata.category_pct}%<br>' +\n 'Percent of all: %{customdata.total_pct}%' +\n '<extra></extra>'\n )\n ))\n \n # Update layout with improved legend\n fig.update_layout(\n xaxis={\"title\": \"Type of version required to fix vulnerability\"},\n yaxis={\"title\": \"Vulnerability count\"},\n barmode='group',\n bargap=0.15,\n bargroupgap=0.05,\n margin=dict(l=0, r=0, t=60, b=60),\n legend=dict(\n orientation=\"v\",\n yanchor=\"top\",\n y=0.95,\n xanchor=\"left\",\n x=1.02,\n title=dict(\n text=\"Severity Level<br><sub>Solid: Direct | Striped: Transitive</sub>\",\n font=dict(size=12)\n )\n ),\n annotations=[\n dict(\n text=\"<b>Dependency Vulnerabilities by Fix Type</b>\",\n xref=\"paper\",\n yref=\"paper\",\n x=0.5,\n y=1.05,\n showarrow=False,\n font=dict(size=14)\n )\n ]\n )\n \n return fig\n\n\n# Exit early if there are no stack traces and render a plot with a message\nif len(df) == 0:\n fig = create_bar_plot(None, None)\n fig.update_yaxes(range=[0, 10])\n fig.show(render=\"plotly_mimetype\")\nelse:\n\n def get_semver_fix(version, fixed_version):\n \"\"\"\n looks at current version and fixed version and determines if the fix is a major, minor, patch version, or no fix\n \"\"\"\n version_components = version.split(\".\")\n fixed_components = fixed_version.split(\".\")\n\n # if fixed version is empty, return \"No fixed version\"\n if fixed_version == \"\":\n return \"No fixed version\"\n\n if len(version_components) < 3:\n # fill in the missing version components with 0\n for i in range(3 - len(version_components)):\n version_components.append(\"0\")\n if len(fixed_components) < 3:\n # fill in the missing version components with 0\n for i in range(3 - len(fixed_components)):\n fixed_components.append(\"0\")\n\n elif version_components[0] != fixed_components[0]:\n return \"Major\"\n elif version_components[1] != fixed_components[1]:\n return \"Minor\"\n elif version_components[2] != fixed_components[2]:\n return \"Patch\"\n else:\n return \"Unknown\"\n\n # drop unnecessary columns except depth which we need\n df = df.drop(\n columns=[\n \"repositoryOrigin\",\n \"repositoryPath\",\n \"repositoryBranch\",\n \"repositoryWithBranch\",\n \"cve\",\n \"groupId\",\n \"artifactId\",\n \"summary\",\n ]\n )\n\n # fill NaN values with empty string\n df[\"fixedVersion\"] = df[\"fixedVersion\"].fillna(\"\")\n df[\"version\"] = df[\"version\"].fillna(\"\")\n # make sure version and fixedVersion is a string\n df[\"fixedVersion\"] = df[\"fixedVersion\"].astype(str)\n df[\"version\"] = df[\"version\"].astype(str)\n\n # add column 'semverFix' to dataframe\n df[\"semverFix\"] = df.apply(\n lambda x: get_semver_fix(x[\"version\"], x[\"fixedVersion\"]), axis=1\n )\n \n # Split into direct and transitive\n df_direct = df[df[\"depth\"] == 0]\n df_transitive = df[df[\"depth\"] != 0]\n \n # Define the order for fix types\n fix_order = [\"Patch\", \"Minor\", \"Major\", \"No fixed version\"]\n \n # Create aggregated data for direct dependencies\n direct_data = []\n for fix_type in fix_order:\n fix_df = df_direct[df_direct[\"semverFix\"] == fix_type]\n severity_counts = fix_df[\"severity\"].value_counts()\n direct_data.append({\n \"Type\": fix_type,\n \"Critical\": severity_counts.get(\"CRITICAL\", 0),\n \"High\": severity_counts.get(\"HIGH\", 0),\n \"Moderate\": severity_counts.get(\"MODERATE\", 0),\n \"Low\": severity_counts.get(\"LOW\", 0)\n })\n df_direct_plot = pd.DataFrame(direct_data)\n \n # Create aggregated data for transitive dependencies\n transitive_data = []\n for fix_type in fix_order:\n fix_df = df_transitive[df_transitive[\"semverFix\"] == fix_type]\n severity_counts = fix_df[\"severity\"].value_counts()\n transitive_data.append({\n \"Type\": fix_type,\n \"Critical\": severity_counts.get(\"CRITICAL\", 0),\n \"High\": severity_counts.get(\"HIGH\", 0),\n \"Moderate\": severity_counts.get(\"MODERATE\", 0),\n \"Low\": severity_counts.get(\"LOW\", 0)\n })\n df_transitive_plot = pd.DataFrame(transitive_data)\n\n fig = create_bar_plot(df_direct_plot, df_transitive_plot)\n\n # Show the figure\n fig.show(render=\"plotly_mimetype\")"
1328
22
  }
1329
23
  ],
1330
24
  "metadata": {
@@ -1348,4 +42,4 @@
1348
42
  },
1349
43
  "nbformat": 4,
1350
44
  "nbformat_minor": 4
1351
- }
45
+ }