├── .gitignore ├── README.md ├── data ├── contour.png ├── forest_plot.csv ├── forest_plot.png ├── gld.png ├── img.png ├── img_vs.png ├── img_vs_att.png ├── img_vs_example.png ├── img_vs_heatmap.png ├── performance_boxplot.pdf ├── performance_boxplot.png ├── performance_method1.txt ├── performance_method2.txt ├── performance_method3.txt ├── seaborn_boxplot.csv ├── seaborn_boxplot.pdf ├── seaborn_boxplot.png └── seg.png ├── show_boxplot.py ├── show_boxplot_seaborn.py ├── show_forest_plot.py ├── show_fused_heatmap.py ├── show_segmentation_contour.py └── show_segmentation_views.py /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.pyc 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vis_tool 2 | Python scripts to visualize exeprimental results for image computing researches 3 | 4 | # Functions: 5 | 1, Visualize a segmentation result compared with the ground truth. 6 | ```bash 7 | python show_segmentation_contour.py 8 | ``` 9 | 10 | 11 | In this example, the ground truth is shown in yellow color and the segmentation is shown with green color. 12 | 13 | 14 | 2, Use boxplot to compare the performance of different methods on a set of data. 15 | ```bash 16 | python show_boxplot.py 17 | ``` 18 | 19 | 20 | 3, Use seaborn to show boxplot. 21 | ```bash 22 | python show_boxplot_seaborn.py 23 | ``` 24 | 25 | 26 | 4, Fuse a heatmap with an image 27 | ```bash 28 | python show_fused_heatmap.py 29 | ``` 30 | 31 | 32 | 5, Show forest plot of logitic regression 33 | ``` 34 | python show_forest_plot.py 35 | ``` 36 | -------------------------------------------------------------------------------- /data/contour.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taigw/vis_tool/e3c4c4b63055213f6e127bc609aa1dac1f6f823b/data/contour.png -------------------------------------------------------------------------------- /data/forest_plot.csv: -------------------------------------------------------------------------------- 1 | measure,pvalue,OR,lower,upper,weight 2 | x1,0.0001,1.34,0.39,4.59,0.3 3 | x2,0.0023,2.92,1.12,8.65,1.02 4 | x3,1.23E-02,0.17,0.04,0.62,-1.85 5 | x4,0.0004,1.57,0.69,3.45,0.5 6 | x5,0.0232,0.65,0.21,1.98,-0.45 7 | -------------------------------------------------------------------------------- /data/forest_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taigw/vis_tool/e3c4c4b63055213f6e127bc609aa1dac1f6f823b/data/forest_plot.png -------------------------------------------------------------------------------- /data/gld.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taigw/vis_tool/e3c4c4b63055213f6e127bc609aa1dac1f6f823b/data/gld.png -------------------------------------------------------------------------------- /data/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taigw/vis_tool/e3c4c4b63055213f6e127bc609aa1dac1f6f823b/data/img.png -------------------------------------------------------------------------------- /data/img_vs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taigw/vis_tool/e3c4c4b63055213f6e127bc609aa1dac1f6f823b/data/img_vs.png -------------------------------------------------------------------------------- /data/img_vs_att.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taigw/vis_tool/e3c4c4b63055213f6e127bc609aa1dac1f6f823b/data/img_vs_att.png -------------------------------------------------------------------------------- /data/img_vs_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taigw/vis_tool/e3c4c4b63055213f6e127bc609aa1dac1f6f823b/data/img_vs_example.png -------------------------------------------------------------------------------- /data/img_vs_heatmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taigw/vis_tool/e3c4c4b63055213f6e127bc609aa1dac1f6f823b/data/img_vs_heatmap.png -------------------------------------------------------------------------------- /data/performance_boxplot.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taigw/vis_tool/e3c4c4b63055213f6e127bc609aa1dac1f6f823b/data/performance_boxplot.pdf -------------------------------------------------------------------------------- /data/performance_boxplot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taigw/vis_tool/e3c4c4b63055213f6e127bc609aa1dac1f6f823b/data/performance_boxplot.png -------------------------------------------------------------------------------- /data/performance_method1.txt: -------------------------------------------------------------------------------- 1 | 63.6 51.6 46.8 84 48 57.6 112.8 36 61.2 86.4 38.4 58.8 51.6 69.6 66 2 | 115.8 -------------------------------------------------------------------------------- /data/performance_method2.txt: -------------------------------------------------------------------------------- 1 | 334 114 95 94 170 184 205 111 105 235 86 256 103 192 227 -------------------------------------------------------------------------------- /data/performance_method3.txt: -------------------------------------------------------------------------------- 1 | 158.4 171.6 136.8 53.2 196.8 164.4 204 168 288 141.6 207.6 206.4 108 151.2 216 2 | 158.4 171.6 136.8 55.2 196.8 164.4 204 168 288 141.6 207.6 206.4 108 151.2 216 -------------------------------------------------------------------------------- /data/seaborn_boxplot.csv: -------------------------------------------------------------------------------- 1 | mage_id,Group,Metric 1,Metric 2,Metric 3,Method 2 | 1.00E+00,Group A,7.22E-01,3.13E-02,9.93E+01,Method 1 3 | 2.00E+00,Group A,8.57E-01,1.82E-01,1.25E+00,Method 1 4 | 3.00E+00,Group A,6.41E-01,4.50E-01,8.24E+00,Method 1 5 | 4.00E+00,Group A,5.96E-01,5.76E-01,5.19E+01,Method 1 6 | 5.00E+00,Group A,4.35E-01,3.85E-01,8.96E+01,Method 1 7 | 6.00E+00,Group A,7.78E-01,1.22E-01,1.37E+01,Method 1 8 | 7.00E+00,Group A,7.28E-01,1.07E-02,7.35E+01,Method 1 9 | 8.00E+00,Group A,6.64E-01,4.59E-01,6.04E+00,Method 1 10 | 9.00E+00,Group A,8.80E-01,1.25E-02,1.23E+01,Method 1 11 | 1.00E+01,Group A,5.19E-01,1.34E-01,2.07E+02,Method 1 12 | 1.10E+01,Group A,8.63E-01,7.31E-02,2.42E+00,Method 1 13 | 1.20E+01,Group A,8.75E-01,1.90E-01,4.97E+00,Method 1 14 | 1.30E+01,Group A,5.39E-01,5.14E-01,4.07E+01,Method 1 15 | 1.40E+01,Group A,8.73E-01,2.99E-02,3.43E+01,Method 1 16 | 1.50E+01,Group A,5.06E-01,4.18E-01,1.83E+01,Method 1 17 | 2.30E+01,Group B,5.63E-01,6.50E-01,2.15E+01,Method 1 18 | 2.40E+01,Group B,9.17E-01,5.28E-04,4.44E+00,Method 1 19 | 2.50E+01,Group B,7.82E-01,9.88E-02,1.45E+01,Method 1 20 | 2.60E+01,Group B,8.03E-01,2.47E-01,9.04E+00,Method 1 21 | 2.70E+01,Group B,8.80E-01,1.30E-01,4.32E+00,Method 1 22 | 2.80E+01,Group B,8.94E-01,1.33E-02,4.86E+00,Method 1 23 | 2.90E+01,Group B,8.06E-01,7.77E-03,5.86E+00,Method 1 24 | 3.00E+01,Group B,6.81E-01,3.54E-01,8.31E+01,Method 1 25 | 3.10E+01,Group B,8.28E-01,3.65E-02,8.49E+00,Method 1 26 | 3.20E+01,Group B,7.95E-01,5.10E-02,1.06E+01,Method 1 27 | 3.30E+01,Group B,7.62E-01,3.49E-01,2.14E+01,Method 1 28 | 3.40E+01,Group B,8.69E-01,3.27E-02,1.00E+01,Method 1 29 | 3.50E+01,Group B,7.93E-01,4.62E-02,7.16E+00,Method 1 30 | 3.60E+01,Group B,8.13E-01,7.40E-02,5.32E+01,Method 1 31 | 3.70E+01,Group B,8.17E-01,2.51E-01,1.04E+01,Method 1 32 | 5.80E+01,Group C,8.48E-01,1.62E-01,5.00E+00,Method 1 33 | 5.90E+01,Group C,8.88E-01,2.32E-02,5.25E+00,Method 1 34 | 6.00E+01,Group C,9.02E-01,9.05E-02,2.96E+00,Method 1 35 | 6.10E+01,Group C,8.62E-01,1.36E-01,1.00E+01,Method 1 36 | 6.20E+01,Group C,7.78E-01,2.43E-01,1.03E+01,Method 1 37 | 6.30E+01,Group C,8.63E-01,3.21E-02,5.65E+00,Method 1 38 | 6.40E+01,Group C,8.22E-01,1.69E-01,3.88E+01,Method 1 39 | 6.50E+01,Group C,8.15E-01,3.21E-03,1.09E+01,Method 1 40 | 6.60E+01,Group C,4.75E-01,1.90E+00,3.52E+01,Method 1 41 | 6.70E+01,Group C,9.01E-01,6.46E-02,8.33E+00,Method 1 42 | 6.80E+01,Group C,8.53E-01,1.45E-01,5.00E+00,Method 1 43 | 6.90E+01,Group C,8.63E-01,2.16E-01,5.35E+00,Method 1 44 | 7.00E+01,Group C,6.20E-01,3.17E-01,1.97E+01,Method 1 45 | 7.10E+01,Group C,8.27E-01,2.02E-01,6.94E+00,Method 1 46 | 7.20E+01,Group C,8.98E-01,8.09E-03,5.00E+00,Method 1 47 | 1.00E+00,Group A,7.29E-01,2.89E-01,8.97E+01,Method 2 48 | 2.00E+00,Group A,8.75E-01,1.58E-01,1.41E+00,Method 2 49 | 3.00E+00,Group A,6.20E-01,5.42E-01,9.74E+00,Method 2 50 | 4.00E+00,Group A,6.08E-01,6.17E-01,5.19E+01,Method 2 51 | 5.00E+00,Group A,5.36E-01,3.35E-01,8.63E+01,Method 2 52 | 6.00E+00,Group A,7.21E-01,4.03E-01,1.30E+01,Method 2 53 | 7.00E+00,Group A,7.27E-01,2.93E-02,4.10E+01,Method 2 54 | 8.00E+00,Group A,7.55E-01,3.18E-01,4.10E+00,Method 2 55 | 9.00E+00,Group A,8.99E-01,1.05E-01,1.03E+01,Method 2 56 | 1.00E+01,Group A,6.08E-01,9.67E-02,1.76E+02,Method 2 57 | 1.10E+01,Group A,8.66E-01,6.37E-02,3.35E+00,Method 2 58 | 1.20E+01,Group A,8.60E-01,2.86E-01,5.00E+00,Method 2 59 | 1.30E+01,Group A,6.26E-01,3.67E-01,2.72E+01,Method 2 60 | 1.40E+01,Group A,8.76E-01,9.86E-02,1.50E+02,Method 2 61 | 1.50E+01,Group A,5.18E-01,5.17E-01,2.28E+01,Method 2 62 | 2.30E+01,Group B,4.91E-01,6.32E-01,4.35E+01,Method 2 63 | 2.40E+01,Group B,9.08E-01,7.96E-02,5.06E+00,Method 2 64 | 2.50E+01,Group B,7.81E-01,1.05E-01,1.34E+01,Method 2 65 | 2.60E+01,Group B,8.30E-01,1.90E-01,3.75E+00,Method 2 66 | 2.70E+01,Group B,8.89E-01,1.19E-01,2.85E+00,Method 2 67 | 2.80E+01,Group B,9.32E-01,0.00E+00,1.46E+00,Method 2 68 | 2.90E+01,Group B,8.12E-01,8.14E-05,2.24E+01,Method 2 69 | 3.00E+01,Group B,7.09E-01,3.59E-01,8.75E+01,Method 2 70 | 3.10E+01,Group B,8.24E-01,1.81E-02,5.95E+00,Method 2 71 | 3.20E+01,Group B,8.09E-01,4.80E-03,1.31E+01,Method 2 72 | 3.30E+01,Group B,7.96E-01,2.10E-01,1.95E+01,Method 2 73 | 3.40E+01,Group B,8.84E-01,2.61E-02,5.05E+00,Method 2 74 | 3.50E+01,Group B,8.14E-01,1.52E-01,5.05E+00,Method 2 75 | 3.60E+01,Group B,8.45E-01,8.96E-02,1.80E+01,Method 2 76 | 3.70E+01,Group B,8.70E-01,1.71E-01,6.62E+00,Method 2 77 | 5.80E+01,Group C,8.41E-01,2.19E-01,5.00E+00,Method 2 78 | 5.90E+01,Group C,8.97E-01,3.44E-02,5.20E+00,Method 2 79 | 6.00E+01,Group C,9.17E-01,6.71E-02,2.44E+00,Method 2 80 | 6.10E+01,Group C,8.66E-01,1.25E-01,1.72E+01,Method 2 81 | 6.20E+01,Group C,8.20E-01,2.20E-01,1.00E+01,Method 2 82 | 6.30E+01,Group C,8.68E-01,2.14E-02,4.68E+00,Method 2 83 | 6.40E+01,Group C,8.27E-01,5.37E-02,4.16E+01,Method 2 84 | 6.50E+01,Group C,8.14E-01,2.64E-04,1.09E+01,Method 2 85 | 6.60E+01,Group C,4.78E-01,1.65E+00,3.61E+01,Method 2 86 | 6.70E+01,Group C,9.01E-01,1.02E-01,6.92E+00,Method 2 87 | 6.80E+01,Group C,8.67E-01,1.19E-01,5.00E+00,Method 2 88 | 6.90E+01,Group C,8.77E-01,1.56E-01,5.00E+00,Method 2 89 | 7.00E+01,Group C,5.45E-01,3.81E-01,2.09E+01,Method 2 90 | 7.10E+01,Group C,8.32E-01,1.82E-01,7.22E+00,Method 2 91 | 7.20E+01,Group C,8.90E-01,8.82E-03,5.00E+00,Method 2 92 | 1.00E+00,Group A,7.88E-01,2.74E-01,2.50E+00,Method 3 93 | 2.00E+00,Group A,8.67E-01,1.63E-01,1.41E+00,Method 3 94 | 3.00E+00,Group A,6.72E-01,4.64E-01,8.43E+00,Method 3 95 | 4.00E+00,Group A,6.23E-01,5.18E-01,5.39E+01,Method 3 96 | 5.00E+00,Group A,5.36E-01,2.27E-01,9.28E+01,Method 3 97 | 6.00E+00,Group A,7.57E-01,3.09E-01,1.25E+01,Method 3 98 | 7.00E+00,Group A,7.34E-01,4.19E-02,3.93E+01,Method 3 99 | 8.00E+00,Group A,7.22E-01,3.83E-01,4.95E+00,Method 3 100 | 9.00E+00,Group A,9.06E-01,5.42E-02,8.56E+00,Method 3 101 | 1.00E+01,Group A,5.62E-01,1.02E-01,1.72E+02,Method 3 102 | 1.10E+01,Group A,8.86E-01,1.82E-02,1.42E+00,Method 3 103 | 1.20E+01,Group A,8.43E-01,3.41E-01,5.00E+00,Method 3 104 | 1.30E+01,Group A,3.91E-01,6.68E-01,2.59E+01,Method 3 105 | 1.40E+01,Group A,8.67E-01,1.04E-01,1.51E+02,Method 3 106 | 1.50E+01,Group A,5.54E-01,4.13E-01,1.90E+01,Method 3 107 | 2.30E+01,Group B,5.31E-01,5.61E-01,2.90E+01,Method 3 108 | 2.40E+01,Group B,9.14E-01,1.08E-03,4.37E+00,Method 3 109 | 2.50E+01,Group B,7.93E-01,1.59E-02,1.20E+01,Method 3 110 | 2.60E+01,Group B,8.56E-01,1.52E-01,7.50E+00,Method 3 111 | 2.70E+01,Group B,9.01E-01,1.00E-01,2.98E+00,Method 3 112 | 2.80E+01,Group B,9.27E-01,4.44E-02,1.46E+00,Method 3 113 | 2.90E+01,Group B,8.11E-01,4.73E-02,6.07E+00,Method 3 114 | 3.00E+01,Group B,6.06E-01,5.21E-01,8.77E+01,Method 3 115 | 3.10E+01,Group B,8.23E-01,3.11E-02,7.62E+00,Method 3 116 | 3.20E+01,Group B,8.26E-01,1.65E-02,8.86E+00,Method 3 117 | 3.30E+01,Group B,7.88E-01,2.83E-01,2.13E+01,Method 3 118 | 3.40E+01,Group B,8.87E-01,1.94E-02,9.70E+00,Method 3 119 | 3.50E+01,Group B,8.39E-01,7.81E-04,5.09E+00,Method 3 120 | 3.60E+01,Group B,8.43E-01,1.10E-03,1.80E+01,Method 3 121 | 3.70E+01,Group B,8.88E-01,1.25E-01,5.77E+00,Method 3 122 | 5.80E+01,Group C,8.69E-01,9.62E-02,4.29E+00,Method 3 123 | 5.90E+01,Group C,8.83E-01,4.73E-02,5.99E+00,Method 3 124 | 6.00E+01,Group C,9.23E-01,4.09E-02,2.38E+00,Method 3 125 | 6.10E+01,Group C,8.67E-01,1.32E-01,2.07E+01,Method 3 126 | 6.20E+01,Group C,8.65E-01,7.35E-02,5.05E+00,Method 3 127 | 6.30E+01,Group C,8.67E-01,5.64E-03,5.65E+00,Method 3 128 | 6.40E+01,Group C,8.52E-01,6.12E-02,3.35E+01,Method 3 129 | 6.50E+01,Group C,8.11E-01,3.90E-02,1.18E+01,Method 3 130 | 6.60E+01,Group C,4.40E-01,2.20E+00,4.04E+01,Method 3 131 | 6.70E+01,Group C,9.09E-01,9.70E-03,3.49E+00,Method 3 132 | 6.80E+01,Group C,8.75E-01,5.50E-02,5.00E+00,Method 3 133 | 6.90E+01,Group C,8.71E-01,1.95E-01,5.55E+00,Method 3 134 | 7.00E+01,Group C,6.72E-01,1.37E-01,2.00E+01,Method 3 135 | 7.10E+01,Group C,8.37E-01,1.82E-01,7.09E+00,Method 3 136 | 7.20E+01,Group C,8.99E-01,1.46E-02,5.00E+00,Method 3 137 | -------------------------------------------------------------------------------- /data/seaborn_boxplot.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taigw/vis_tool/e3c4c4b63055213f6e127bc609aa1dac1f6f823b/data/seaborn_boxplot.pdf -------------------------------------------------------------------------------- /data/seaborn_boxplot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taigw/vis_tool/e3c4c4b63055213f6e127bc609aa1dac1f6f823b/data/seaborn_boxplot.png -------------------------------------------------------------------------------- /data/seg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/taigw/vis_tool/e3c4c4b63055213f6e127bc609aa1dac1f6f823b/data/seg.png -------------------------------------------------------------------------------- /show_boxplot.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from numpy import loadtxt 3 | import matplotlib.pyplot as plt 4 | 5 | def show_performance(): 6 | method_names = ['Method1','Method2','Method3'] 7 | data_file_names = ['data/performance_method1.txt', 8 | 'data/performance_method2.txt', 9 | 'data/performance_method3.txt'] 10 | output_name = 'data/performance_boxplot.pdf' 11 | Data = [np.array(loadtxt(item)) for item in data_file_names] 12 | 13 | fig=plt.figure(figsize=(2.5, 2.5)) 14 | x=[1,2,3] 15 | plt.boxplot(Data) 16 | ylabel = "Performance" 17 | plt.ylim(0, 350) 18 | plt.ylabel(ylabel) 19 | plt.xticks(x, method_names,rotation=30,ha='right') 20 | plt.subplots_adjust(left=0.3, right=0.8, top=0.95, bottom=0.25) 21 | plt.show() 22 | fig.savefig(output_name) 23 | 24 | show_performance() 25 | -------------------------------------------------------------------------------- /show_boxplot_seaborn.py: -------------------------------------------------------------------------------- 1 | import matplotlib 2 | import matplotlib.pyplot as plt 3 | import seaborn as sns 4 | import pandas as pd 5 | 6 | plt.rcParams["font.family"] = "Times New Roman" 7 | plt.rcParams["font.weight"] = 'normal' 8 | 9 | expr = 2 10 | csv_file = "data/seaborn_boxplot.csv" 11 | savename = "data/seaborn_boxplot.pdf" 12 | metrics = ['Metric 1', 'Metric 2', "Metric 3"] 13 | data = pd.read_csv(csv_file) 14 | 15 | flierprops = dict(marker = '.', markerfacecolor = '1.0', markersize = 1, linestyle = 'none') 16 | sns.set_context("paper", font_scale = 0.6) 17 | fig = plt.figure(figsize = (7.5, 1.35), dpi = 300) 18 | 19 | plt.subplot(1,3,1) 20 | #sns.set(style = "whitegrid") 21 | ax = sns.boxplot(x = "Group", y = metrics[0], hue = "Method", linewidth=.5, 22 | data = data, flierprops = flierprops) 23 | plt.ylabel(metrics[0]) 24 | plt.xlabel('') 25 | plt.ylim(0.2, 1) 26 | ax.get_legend().remove() 27 | 28 | plt.subplot(1,3,2) 29 | #sns.set(style = "whitegrid") 30 | ax = sns.boxplot(x = "Group", y = metrics[1], hue = "Method",linewidth=.5, 31 | data = data, flierprops = flierprops) 32 | plt.ylabel(metrics[1]) 33 | plt.xlabel('') 34 | plt.ylim(0, 1) 35 | plt.legend().remove() 36 | 37 | plt.subplot(1,3,3) 38 | #sns.set(style = "whitegrid") 39 | ax = sns.boxplot(x = "Group", y = metrics[2], hue = "Method", linewidth=.5, 40 | data = data, flierprops = flierprops) 41 | plt.ylabel(metrics[2]) 42 | plt.xlabel('') 43 | plt.ylim(0, 120 ) 44 | 45 | plt.legend(bbox_to_anchor=(1.1, 1), loc=2, borderaxespad=0.) 46 | plt.subplots_adjust(left = 0.075, right = 0.8, bottom = 0.2, wspace = 0.55) 47 | 48 | plt.show() 49 | fig.savefig(savename) -------------------------------------------------------------------------------- /show_forest_plot.py: -------------------------------------------------------------------------------- 1 | 2 | import csv 3 | import math 4 | import pandas as pd 5 | import numpy as np 6 | import matplotlib.pyplot as plt 7 | 8 | def create_forest_plot(input_csv, output_png): 9 | items = pd.read_csv(input_csv) 10 | names = list(items.iloc[:, 0]) 11 | pvalue= list(items.iloc[:, 1]) 12 | oddratio = list(items.iloc[:, 2]) 13 | lower = list(items.iloc[:, 3]) 14 | upper = list(items.iloc[:, 4]) 15 | weight= list(items.iloc[:, 5]) 16 | lab_n = len(names) 17 | labels = ["{0:} (pvalue = {1:})".format(names[n], pvalue[n]) \ 18 | for n in range(lab_n)] 19 | 20 | fig, ax = plt.subplots(1, 1, figsize = (7.5, 2.5)) 21 | secax_lab = [] 22 | for n in range(lab_n): 23 | y = lab_n - n 24 | x0 = lower[n] 25 | x1 = upper[n] 26 | xc = oddratio[n] 27 | plt.plot([x0, x1], [y, y], color = 'b') 28 | plt.plot(xc, y, 'd', color='b') 29 | 30 | ci = "({0:.2f}, {1:.2f})".format(x0, x1) 31 | ci = ci + " "*(15- len(ci)) 32 | temp_lab = "{0:.2f} {1:} {2:.2f}".format(xc, ci, weight[n]) 33 | secax_lab.append(temp_lab) 34 | xmin = np.asarray(lower).min() 35 | xmax = math.ceil(np.asarray(upper).max()) 36 | plt.xlim(0.01, xmax) 37 | plt.xticks([0.01, xmax], [0.01, "{0:}".format(xmax)]) 38 | plt.yticks(range(1, lab_n + 1), reversed(labels)) 39 | plt.ylim(0, lab_n + 0.5) 40 | ax.spines['top'].set_color('white') 41 | ax.spines['right'].set_color('white') 42 | ax.spines['left'].set_color('white') 43 | ax.tick_params(axis='y', **{'length':0}) 44 | 45 | secax_y = ax.secondary_yaxis('right') 46 | secax_y.set_yticks(range(1, lab_n + 1)) 47 | secax_y.set_yticklabels(reversed(secax_lab)) 48 | secax_y.tick_params(axis='y', **{'length':0}) 49 | plt.text(xmax, lab_n + 0.5, " OR") 50 | plt.text(xmax + 3, lab_n + 0.5, " 95% CI") 51 | plt.text(xmax + 8.5, lab_n + 0.5, " Weight") 52 | plt.plot([1, 1], [0, lab_n + 0.5], color = 'black', linewidth=1) 53 | plt.subplots_adjust(left=0.28, right=0.72, top=0.8, bottom=0.1) 54 | plt.savefig(output_png) 55 | plt.show() 56 | 57 | input_csv = "./data/forest_plot.csv" 58 | output_png= "./data/forest_plot.png" 59 | create_forest_plot(input_csv, output_png) 60 | -------------------------------------------------------------------------------- /show_fused_heatmap.py: -------------------------------------------------------------------------------- 1 | import os 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | from PIL import Image 5 | 6 | def map_scalar_to_color(x): 7 | x_list = [0.0, 0.25, 0.5, 0.75, 1.0] 8 | c_list = [[0, 0, 255], 9 | [0, 255, 255], 10 | [0, 255, 0], 11 | [255, 255, 0], 12 | [255, 0, 0]] 13 | for i in range(len(x_list)): 14 | if(x <= x_list[i + 1]): 15 | x0 = x_list[i] 16 | x1 = x_list[i + 1] 17 | c0 = c_list[i] 18 | c1 = c_list[i + 1] 19 | alpha = (x - x0)/(x1 - x0) 20 | c = [c0[j]*(1 - alpha) + c1[j] * alpha for j in range(3)] 21 | c = [int(item) for item in c] 22 | return tuple(c) 23 | 24 | def get_fused_heat_map(image, att): 25 | [H, W] = image.size 26 | img = Image.new('RGB', image.size, (255, 0, 0)) 27 | 28 | for i in range(H): 29 | for j in range(W): 30 | p0 = image.getpixel((i,j)) 31 | alpha = att.getpixel((i,j)) 32 | p1 = map_scalar_to_color(alpha) 33 | alpha = 0.5 + alpha*0.3 34 | p = [int(p0[c] * (1 - alpha) + p1[c]*alpha) for c in range(3)] 35 | p = tuple(p) 36 | img.putpixel((i,j), p) 37 | return img 38 | 39 | if __name__ == "__main__": 40 | image_name = "data/img_vs.png" 41 | scalar_name = "data/img_vs_att.png" 42 | save_name = "data/img_vs_heatmap.png" 43 | img = Image.open(image_name) 44 | # load the scalar map, and normalize the inteinsty to 0 - 1 45 | scl = Image.open(scalar_name).convert('L') 46 | scl_norm = np.asarray(scl, np.float32)/255 47 | scl_norm = Image.fromarray(scl_norm) 48 | 49 | # convert the scalar map to heat map, and fuse it with the original image 50 | img_scl = get_fused_heat_map(img, scl_norm) 51 | img_scl.save(save_name) 52 | 53 | plt.subplot(1,3,1), plt.axis('off') 54 | plt.imshow(img), plt.title('image') 55 | plt.subplot(1,3,2), plt.axis('off') 56 | plt.imshow(scl), plt.title('foreground attention') 57 | plt.subplot(1,3,3), plt.axis('off') 58 | plt.imshow(img_scl), plt.title('fused result') 59 | plt.show() 60 | 61 | -------------------------------------------------------------------------------- /show_segmentation_contour.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import scipy 3 | from scipy import ndimage 4 | from PIL import Image 5 | import matplotlib.pyplot as plt 6 | 7 | def add_countor(In, Seg, Color=(0, 255, 0)): 8 | """ 9 | add segmentation contour to an input image 10 | 11 | In: Input PIL.Image object, should be an RGB image 12 | Seg: segmentation mask represented by a PIL.Image object 13 | Color: a vector specifying the color of contour 14 | Out: output PIL.Image object with segmentation contour overlayed 15 | """ 16 | Out = In.copy() 17 | [H, W] = In.size 18 | for i in range(H): 19 | for j in range(W): 20 | if(i==0 or i==H-1 or j==0 or j == W-1): 21 | if(Seg.getpixel((i,j))!=0): 22 | Out.putpixel((i,j), Color) 23 | elif(Seg.getpixel((i,j))!=0 and \ 24 | not(Seg.getpixel((i-1,j))!=0 and \ 25 | Seg.getpixel((i+1,j))!=0 and \ 26 | Seg.getpixel((i,j-1))!=0 and \ 27 | Seg.getpixel((i,j+1))!=0)): 28 | Out.putpixel((i,j), Color) 29 | return Out 30 | 31 | 32 | def add_segmentation(image, seg_name, Color=(0, 255, 0)): 33 | seg = Image.open(seg_name).convert('L') 34 | if(image.size[1] != seg.size[1] or image.size[0] != seg.size[0]): 35 | print('segmentation has been resized') 36 | seg = seg.resize(image.size) 37 | seg = np.asarray(seg) 38 | strt = ndimage.generate_binary_structure(2, 1) 39 | seg = np.asarray(ndimage.morphology.binary_opening(seg, strt), np.uint8) 40 | seg = np.asarray(ndimage.morphology.binary_closing(seg, strt), np.uint8) 41 | 42 | img_show = add_countor(image, Image.fromarray(seg), Color) 43 | strt = ndimage.generate_binary_structure(2, 1) 44 | seg = np.asarray(ndimage.morphology.binary_dilation(seg, strt), np.uint8) 45 | img_show = add_countor(img_show, Image.fromarray(seg), Color) 46 | return img_show 47 | 48 | if __name__ == "__main__": 49 | img_name = "data/img.png" 50 | seg_name = "data/seg.png" 51 | gld_name = "data/gld.png" 52 | img = Image.open(img_name) 53 | img_show = add_segmentation(img, gld_name, Color = (255, 255, 0)) 54 | img_show = add_segmentation(img_show, seg_name, Color = (0, 255, 0)) 55 | plt.imshow(img_show) 56 | plt.axis('off') 57 | plt.show() 58 | save_name = "data/contour.png" 59 | img_show.save(save_name) 60 | -------------------------------------------------------------------------------- /show_segmentation_views.py: -------------------------------------------------------------------------------- 1 | import os 2 | import SimpleITK as sitk 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | from scipy.ndimage import gaussian_filter 6 | from PIL import Image 7 | from PIL import ImageFilter 8 | 9 | def gray_to_rgb(image): 10 | """ 11 | convert a gray-scale image to RGB image 12 | 13 | image: an input 2D numpy array with shape [H, W] 14 | image_cat: a output numpy array with shape [H, W, 3] 15 | """ 16 | image_cat = np.asarray([image, image, image]) 17 | image_cat = np.transpose(image_cat, [1, 2, 0]) 18 | return image_cat 19 | 20 | 21 | def get_slice_from_volume(image, view, slice_id): 22 | """ 23 | extract a slice form a volume image 24 | 25 | image: a 3D numpy array with shape of [D, H, W] 26 | view : 0 -- axial, 1 -- sagittal, 2 -- coronal 27 | slice_id: slice index in the given view 28 | """ 29 | if(view == 1): 30 | image = np.transpose(image, [2, 0, 1]) 31 | elif(view == 2): 32 | image = np.transpose(image, [1, 0, 2]) 33 | return image[slice_id] 34 | 35 | 36 | def add_contour(In, Seg, Color=(0, 255, 0)): 37 | """ 38 | add segmentation contour to an input image 39 | 40 | In: Input PIL.Image object, should be an RGB image 41 | Seg: segmentation mask represented by a PIL.Image object 42 | Color: a vector specifying the color of contour 43 | Out: output PIL.Image object with segmentation contour overlayed 44 | """ 45 | Out = In.copy() 46 | [H, W] = In.size 47 | for i in range(H): 48 | for j in range(W): 49 | if(i==0 or i==H-1 or j==0 or j == W-1): 50 | if(Seg.getpixel((i,j))!=0): 51 | Out.putpixel((i,j), Color) 52 | elif(Seg.getpixel((i,j))!=0 and \ 53 | not(Seg.getpixel((i-1,j))!=0 and \ 54 | Seg.getpixel((i+1,j))!=0 and \ 55 | Seg.getpixel((i,j-1))!=0 and \ 56 | Seg.getpixel((i,j+1))!=0)): 57 | Out.putpixel((i,j), Color) 58 | Out.putpixel((i+1,j), Color) 59 | Out.putpixel((i,j+1), Color) 60 | Out.putpixel((i-1,j), Color) 61 | Out.putpixel((i,j-1), Color) 62 | return Out 63 | 64 | def add_segmentation_color(In, Seg, Color=(255, 0, 0), alpha=0.3): 65 | """ 66 | add segmentation mask to an input image 67 | 68 | In: Input PIL.Image object, should be an RGB image 69 | Seg: segmentation mask represented by a PIL.Image object 70 | Color: a vector specifying the color of contour 71 | alpha: alpha value of the mask 72 | Out: output PIL.Image object with segmentation contour overlayed 73 | """ 74 | Out = In.copy() 75 | [H, W] = In.size 76 | for i in range(H): 77 | for j in range(W): 78 | fg = Seg.getpixel((i,j)) 79 | if(fg>0): 80 | color0 = In.getpixel((i,j)) 81 | color1 = (int(color0[0] * (1.0 - alpha) + Color[0] * alpha), 82 | int(color0[1] * (1.0 - alpha) + Color[1] * alpha), 83 | int(color0[2] * (1.0 - alpha) + Color[2] * alpha)) 84 | Out.putpixel((i,j), color1) 85 | return Out 86 | 87 | def get_central_slice_index_of_nonzero_region(image, view): 88 | """ 89 | get the central slice index of nonzero region of a volume 3D 90 | 91 | image: a 3D numpy array 92 | view : 0 -- axial, 1 -- sagittal, 2 -- coronal 93 | """ 94 | [d_index, h_index, w_index] = np.where(image) 95 | if(view == 0): 96 | index_list = d_index 97 | elif(view == 1): 98 | index_list = w_index 99 | else: 100 | index_list = h_index 101 | idx_min = min(index_list) 102 | idx_max = max(index_list) 103 | i_cen = int((idx_min + idx_max)/2) 104 | return i_cen 105 | 106 | def map_scalar_to_color(x): 107 | x_list = [0.0, 0.25, 0.5, 0.75, 1.0] 108 | c_list = [[0, 0, 255], 109 | [0, 255, 255], 110 | [0, 255, 0], 111 | [255, 255, 0], 112 | [255, 0, 0]] 113 | for i in range(len(x_list)): 114 | if(x <= x_list[i + 1]): 115 | x0 = x_list[i] 116 | x1 = x_list[i + 1] 117 | c0 = c_list[i] 118 | c1 = c_list[i + 1] 119 | alpha = (x - x0)/(x1 - x0) 120 | c = [c0[j]*(1 - alpha) + c1[j] * alpha for j in range(3)] 121 | c = [int(item) for item in c] 122 | return tuple(c) 123 | 124 | def show_one_slice(img_folder, lab_folder, method_list, seg_folder_list, img_id, view_id, 125 | slice_id, save_dir = None, contour = False): 126 | img_name = "{0:}/{1:}.nii.gz".format(img_folder, img_id) 127 | lab_name = "{0:}/{1:}.nii.gz".format(lab_folder, img_id) 128 | img_obj = sitk.ReadImage(img_name) 129 | spacing = img_obj.GetSpacing() 130 | scale = spacing[2]/spacing[0] 131 | img = sitk.GetArrayFromImage(img_obj) 132 | 133 | # Rescale the image intensity to [0,255]. 134 | # You may need to edit this according to your data 135 | img = (img + 1400) / 1500 * 255 136 | img[img < 0] = 0 137 | img[img > 255] = 255 138 | img = np.asarray(img, np.uint8) 139 | 140 | # Extract the specified slice from the image and ground truth mask 141 | lab_obj = sitk.ReadImage(lab_name) 142 | lab = sitk.GetArrayFromImage(lab_obj) 143 | img_slc = get_slice_from_volume(img, view_id, slice_id) 144 | lab_slc = get_slice_from_volume(lab, view_id, slice_id) 145 | 146 | im_show_raw = gray_to_rgb(img_slc) 147 | im_show_raw = Image.fromarray(im_show_raw) 148 | lab_slc = Image.fromarray(lab_slc) 149 | 150 | # As the 3D resolution may be anisotropic, resampleing to isotropic 151 | # resolution is needed for better visualization 152 | if(view_id == 1 or view_id == 2): 153 | new_size = [im_show_raw.size[0], int(im_show_raw.size[1] * scale)] 154 | im_show_raw = im_show_raw.resize(new_size) 155 | lab_slc = lab_slc.resize(new_size) 156 | 157 | seg_list = [] 158 | for seg_folder in seg_folder_list: 159 | seg_name = "{0:}/{1:}.nii.gz".format(seg_folder, img_id) 160 | seg_obj = sitk.ReadImage(seg_name) 161 | seg = sitk.GetArrayFromImage(seg_obj) 162 | seg_slc = get_slice_from_volume(seg, view_id, slice_id) 163 | seg_slc = Image.fromarray(seg_slc) 164 | if(view_id == 1 or view_id == 2): 165 | seg_slc = seg_slc.resize(new_size) 166 | seg_list.append(seg_slc) 167 | 168 | plt.figure(figsize=(15, 8)) 169 | im_show = im_show_raw 170 | if(contour): 171 | im_show = add_contour(im_show, lab_slc, (255, 128, 0)) 172 | im_gt = im_show 173 | else: 174 | im_gt = add_segmentation_color(im_show, lab_slc) 175 | N = len(seg_list) 176 | column = int((N + 3) / 2) 177 | plt.subplot(2, column, 1); plt.axis("off") 178 | plt.imshow(im_show_raw); plt.title("image") 179 | plt.subplot(2, column, 2); plt.axis("off") 180 | plt.imshow(im_gt); plt.title("ground_truth") 181 | 182 | if(save_dir): 183 | save_name = "{0:}/{1:}_{2:}_img.png".format(save_dir, img_id, slice_id) 184 | im_show_raw.save(save_name) 185 | save_name = "{0:}/{1:}_{2:}_gt.png".format(save_dir, img_id, slice_id) 186 | im_gt.save(save_name) 187 | for n in range(N): 188 | plt.subplot(2, column, n + 3); plt.axis("off") 189 | if(contour): 190 | im_show_n = add_contour(im_show, seg_list[n]) 191 | else: 192 | im_show_n = add_segmentation_color(im_show, seg_list[n]) 193 | if(save_dir): 194 | save_name = "{0:}/{1:}_{2:}_{3:}_.png".format(save_dir, 195 | img_id, slice_id, method_list[n]) 196 | im_show_n.save(save_name) 197 | plt.imshow(im_show_n); plt.title(method_list[n]) 198 | 199 | plt.show() 200 | 201 | 202 | def show_results_for_comparison(): 203 | """ 204 | show 3d segmentation results in axial, sagittal or coronal views 205 | """ 206 | img_folder = "./image" 207 | lab_folder = "./label" 208 | seg_root = "./net_compare" 209 | methods = ["unet", "unet_att" "unet3d", "vnet"] 210 | seg_folder_list = ["unet2d/result", "unet_att/result", "unet3d/result", "vnet/result"] 211 | seg_folder_list = [seg_root + '/' + item for item in seg_folder_list] 212 | 213 | save_dir= False # "./image1" # 214 | img_id = "image1" 215 | view_id = 0 # 0-axial, 1-sagittal, 2-coronal 216 | slice_id = 50 217 | 218 | show_one_slice(img_folder, lab_folder, methods, seg_folder_list, 219 | img_id, view_id, slice_id, save_dir, contour=False) 220 | 221 | 222 | if __name__ == "__main__": 223 | show_results_for_comparison() 224 | --------------------------------------------------------------------------------