[27c943]: / pathflowai / __pycache__ / visualize.cpython-36.pyc

Download this file

371 lines (339 with data), 19.5 kB

3

ö└A]5MŃ@sýdZddljZddljZddlZddl	Z
ddlZddl
jZddlmZddlZddljZddlZddlZddlZddlmZejâGddädâZddäZd*d
däZdd
äZddäZ ddäZ!d+ddäZ"GddädâZ#d,ddäZ$d-d(d)äZ%dS).zs
visualize.py
=======================
Plots SHAP outputs, UMAP embeddings, and overlays predictions on top of WSI.
ÚN)┌Image)┌joinc@s@eZdZdZddäZdddddd	gd
dgfdd
äZdddäZdS)┌
PlotlyPlotzCreates plotly html plots.cCs
g|_dS)N)┌plots)┌selfęr˙E/Users/joshualevy/Documents/GitHub/PathFlowAI/pathflowai/visualize.py┌__init__szPlotlyPlot.__init__N┌color┌name┌x┌y┌zÚg­?c	szg}	t|â\}
}}||jtjkr~|	jtj||
||||ddt||||dtddŹdŹ|t|âkrn||n||dŹân˘||j	â}
t
jdt|
ââëtj
d	d
äłDââë|rÂ|ëçfddätt|
ââDâ}xá|jâD]ö\}}|	jtj||
|||k|||||k|||||kt|âdt|||d
Źdt|âkÉrT|j|||kn|||||kdŹâq┌W|dk	Érjggg}}}x┤|jâD]Ę}|d|jjkÉrľ|d|jjkÉrľ||j|d|
f|j|d|
fdg7}||j|d|f|j|d|fdg7}||j|d|f|j|d|fdg7}ÉqľW|	jtj|||dtjjdddŹddŹâ|jj|	âdS)aŤAdds plotting data to be plotted.

		Parameters
		----------
		t_data_df:dataframe
			3-D transformed dataframe.
		G:nx.Graph
			Networkx graph.
		color_col:str
			Column to use to color points.
		name_col:str
			Column to use to name points.
		xyz_cols:list
			3 columns that denote x,y,z coords.
		size:int
			Marker size.
		opacity:float
			Marker opacity.
		custom_colors:list
			Custom colors to supply.
		┌┌markers┌ViridisZColorbar)┌title)r
┌size┌opacity┌
colorscale┌colorbar)rr
rr┌mode┌marker┌text┌hlscSs6g|].}djdjtj|âdjtâjtâjâââĹqS)zrgb({})˙,Ú )┌formatr┌np┌array┌astype┌int┌str┌tolist)┌.0Zc_irrr˙
<listcomp>;sz'PlotlyPlot.add_plot.<locals>.<listcomp>csi|]\}}ł||ôqSrr)r%┌ir)┌crr˙
<dictcomp>>sz'PlotlyPlot.add_plot.<locals>.<dictcomp>)r
rrrNrÚ┌lineszrgb(210,210,210)r)r
┌width┌none)rr
rr┌line┌	hoverinfo)┌tuple┌dtyper┌float64┌append┌go┌	Scatter3d┌dict┌list┌unique┌sns┌
color_palette┌lenr ┌	enumerate┌sorted┌itemsr#┌index┌edges┌values┌loc┌	scatter3d┌Liner┌extend)rZ	t_data_df┌GZ	color_colZname_colZxyz_colsrrZ
custom_colorsrrr
r┌colorsZ
color_dictr┌colZXedZYedZZed┌edger)r(r┌add_plotsF0(J
$**0

zPlotlyPlot.add_plotFcCsÇ|r^tj|jtjttddddddddŹtddddddddŹtddddddddŹdŹdŹdŹ}ntj|jdŹ}tj||dd	Źd
S)zÄPlot embedding of patches to html file.

		Parameters
		----------
		output_fname:str
			Output html file.
		axes_off:bool
			Remove axes.

		rTF)r┌	autorange┌showgrid┌zeroline┌showline┌ticks┌showticklabels)┌xaxis┌yaxis┌zaxis)┌scene)┌data┌layout)rU)┌filename┌	auto_openN)r4┌Figurer┌Layoutr6┌py┌plot)rZoutput_fname┌axes_off┌figrrrr\Ws"$zPlotlyPlot.plot)F)┌__name__┌
__module__┌__qualname__┌__doc__r	rJr\rrrrrs>rcCstj|jdâdâS)zpNumpy array to pil.

	Parameters
	----------
	arr:array
		Numpy array.

	Returns
	-------
	Image
		PIL Image.

	┌uint8┌RGB)r┌	fromarrayr!)┌arrrrr┌to_piljsrgšÓ?cCs||d||S)zŢBlend 2 arrays together, mixing with alpha.

	Parameters
	----------
	arr1:array
		Image 1.
	arr2:array
		Image 2.
	alpha:float
		Higher alpha makes image more like image 1.

	Returns
	-------
	array
		Resulting image.

	g­?r)┌arr1┌arr2┌alpharrr┌blendzsrlcCs6||â}x(tdâD]}t||dâ|d|f<qW|S)aConvert probability score to rgb image.

	Parameters
	----------
	prob:float
		Between 0 and 1 score.
	palette:palette
		Pallet converts between prob and color.
	arr:array
		Original array.

	Returns
	-------
	array
		New image colored by prediction score.

	Úr.)┌ranger")┌prob┌paletterfrHr'rrr┌prob2rbgÄsrqcCs&|||âdddůfdjtâ}|S)aColor each pixel by segmentation class.

	Parameters
	----------
	seg:array
		Segmentation mask.
	palette:palette
		Color to RGB map.
	n_segmentation_classes:int
		Total number segmentation classes.

	Returns
	-------
	array
		Returned segmentation image.
	.Nrmr)r!r")┌segrp┌n_segmentation_classes┌imgrrr┌seg2rgbąs"rucCs6||}x(tdâD]}t||dâ|d|f<qW|S)z╬Go from annotation of patch to color.

	Parameters
	----------
	i:int
		Annotation index.
	palette:palette
		Index to color mapping.
	arr:array
		Image array.

	Returns
	-------
	array
		Resulting image.

	rmr.)rnr")r'rprfrHrrr┌annotation2rgb╝srvš@˙test.pngcCsćddlm}m}ddl}|jdâs4||dddddŹn||â}t|j|jâtt	j
|jdd	ůâ|jt
âjââ|jd
Źâ}|j|âdS)zăPlots entire SVS/other image.

	Parameters
	----------
	image_file:str
		Image file.
	compression_factor:float
		Amount to shrink each dimension of image.
	test_image_name:str
		Output image file.

	r)┌svs2dask_array┌npy2daNz.npyiŔTF)┌	tile_size┌overlap┌remove_last┌allow_unknown_chunksizesr)┌dsize┌
interpolation)┌pathflowai.utilsryrz┌cv2┌endswithrg┌resize┌computer0rr ┌shaper!r"r$┌INTER_CUBIC┌save)┌
image_file┌compression_factor┌test_image_nameryrzrérfrjrrr┌plot_image_Ës

$<rîc
@s<eZdZdZdd
däZdd
äZddäZddäZdddäZdS)┌PredictionPlotteraPlots predictions over entire image.

	Parameters
	----------
	dask_arr_dict:dict
		Stores all dask arrays corresponding to all of the images.
	patch_info_db:str
		Patch level information, eg. prediction.
	compression_factor:float
		How much to compress image by.
	alpha:float
		Low value assigns higher weight to prediction over original image.
	patch_size:int
		Patch size.
	no_db:bool
		Don't use patch information.
	plot_annotation:bool
		Plot annotations from patch information.
	segmentation:bool
		Plot segmentation mask.
	n_segmentation_classes:int
		Number segmentation classes.
	input_dir:str
		Input directory.
	annotation_col:str
		Annotation column to plot.
	scaling_factor:float
		Multiplies the prediction scores to make them appear darker on the images when predicting.
	rmšÓ?ÚÓFÚr┌
annotationš­?c
s2||_||_d|_t|	â|_tjdddŹ|_|s˙||_||_	||_
tj|â}
t
jdj|â|
dŹ}|
jâddät|djâjââDâ|_||_tjtt|jjâââd	Ź|_d
|jkr╝d|d
<|dd
ddd|g|_|jtj|jdtjt|jââââ|_|jÉrçfddä|jâDâ|_ddä|j âDâ|_!dS)NrT)┌startZas_cmapzselect * from "{}";)┌concSsi|]\}}|t|âôqSr)r#)r%r'┌arrrr)sz.PredictionPlotter.__init__.<locals>.<dictcomp>rĹ)┌n_colors┌y_predg┌IDrr
┌
patch_sizecs.i|]&}tjtjtłdj|ââddŹâ|ôqS)z{}_mask.npyzr+)┌	mmap_mode)┌da┌
from_arrayr┌loadrr)r%┌slide)┌	input_dirrrr) scSs"i|]\}}|dddůf|ôqS).Nrmr)r%┌k┌vrrrr)"s)"┌segmentation┌scaling_factor┌segmentation_maps┌floatrsr9Zcubehelix_palette┌pred_paletterŐrkrÖ┌sqlite3┌connect┌pd┌read_sqlr┌closer<r8r$┌annotations┌plot_annotationr:r;r7┌keysrp┌columns┌
patch_infor┌isinr r>┌
dask_arr_dict)rr▓Z
patch_info_dbrŐrkrÖ┌no_dbrşrórsrč┌annotation_colrú┌connr░r)rčrr	s,

 
(zPredictionPlotter.__init__cCstjtj|ddŹâ|j|<dS)zőReplace segmentation mask with new custom segmentation.

		Parameters
		----------
		basename:str
			Patient ID
		npy:str
			Numpy mask.
		zr+)rÜN)rŤrťrrŁrĄ)r┌basename┌npyrrr┌add_custom_segmentation$s
z)PredictionPlotter.add_custom_segmentationcCs▓|j|jd|k}|j|}tj|jâjtâ}|ddů|j<|jtâj	â}t
jd|ddůdâ}Éx@t|jdâDÉ],}|j
|j	â\}}}}	}
}t||jât||jâ}}
tj|	|	dfâ}|jÉrt|j||||	ů|||	ůfjâ|j|jâ}n4|jÉs"t||j|j|ânt|jt|â|j|â}||||	ů|||	ůfjâ}t|||jâjd
â}t|â}|	|j}	t|	â}	|j |	|	fâ}|j!|||
fdd	Źq|W|S)z╩Generate the image array for the whole slide image with predictions overlaid.

		Parameters
		----------
		ID:str
			patient ID.

		Returns
		-------
		array
			Resulting overlaid whole slide image.

		rśNrrd┌whiterrmr*)┌box┌mask)r*rr)"r░r▓rr rćr!rąrŐr"r$r┌newrn┌iloc┌zerosrórurĄrůrŽrsrşrqrúrvrČr#rprlrk┌	transposergrä┌paste)rrśr░Zdask_arr┌	arr_shapertr'rr
rÖrĹ┌pred┌x_new┌y_new┌imagerfZ
blended_patchZblended_patch_pilrrr┌generate_image0s*
44 
z PredictionPlotter.generate_imagecCsf|js,|j||||ů|||ůfjân0t|j||||ů|||ůfjâ|j|jâ}t|âS)zŮReturn one single patch instead of entire image.

		Parameters
		----------
		ID:str
			Patient ID
		x:int
			X coordinate.
		y:int
			Y coordinate.
		patch_size:int
			Patch size.

		Returns
		-------
		array
			Image.
		)rór▓růrurĄrŽrsrg)rrśrr
rÖrtrrr┌return_patch]s^zPredictionPlotter.return_patchcCs4|r&ddlm}||tj|âddŹn
|j|âdS)zŤOutput calculated image to file.

		Parameters
		----------
		img:array
			Image.
		filename:str
			Output file name.
		tif:bool
			Store in TIF format?
		r)┌imwrite┌rgb)ZphotometricN)Ztifffiler╚rr rł)rrtrWZtifr╚rrr┌output_imagesszPredictionPlotter.output_imageN)
rmrÄrĆFFFrÉrrĹrĺ)F)	r_r`rarbr	rŞrĂrăr╩rrrrrŹšs
-rŹr*┌deepšÚFc
$s\ddl}
ddlm}ddlëddlm}ddl}
ddlm}ddl	}ddl	m
}ddlm}t
|j|jdd	äd
Ź}|jdâ}|jdâë|f|Ä}|d
r░|jł|dŹ}t|jâë|||dłdkr─dndłdkrÍ||ânddŹëttłââ\}}|dkÉr|
j|ttłââdgdâ}ttłââ\}}|
jjâÉr@|jâ}|jâ}|	dkÉrv|
jjâÉr^|jâ}||	||ââjâjâ}|jâ}|dkÉrĄ|
j||â}|j|łdŹ}n,|dkÉrđ|
j||||dŹ}|j|ł|dŹ}|jddkÉrý|jddŹ}łdkÉr|\}}n
||}}łdkÉr0łj łj |dd%âddâg}nçfddä|Dâ}|jâjâjâ} | j!d&â} xTt"| jdâD]B}!| |!dfłj#|d â9<| |!dfłj#|d!â7<ÉqlW| j!d'â} łj łj | dd(âddâ}"|	dkÉrŕ|j$t%â}#nłj#çççfd"dä|Dââ}#dÉr4t|#jâdkÉs,|#jddkÉr4|#j&â}#|j'â|
j(||"|#â|j)|d#d$ŹdS))aDPlot shapley attributions overlaid on images for classification tasks.

	Parameters
	----------
	model:nn.Module
		Pytorch model.
	dataset_opts:dict
		Options used to configure dataset
	transform_opts:dict
		Options used to configure transformers.
	batch_size:int
		Batch size for training.
	outputfilename:str
		Output filename.
	n_outputs:int
		Number of top outputs.
	method:str
		Gradient or deep explainer.
	local_smoothing:float
		How much to smooth shapley map.
	n_samples:int
		Number shapley samples to draw.
	pred_out:bool
		Label images with binary prediction score?

	rN)┌
functional)┌
DataLoader)┌DynamicImageDataset)┌pyplot)┌ImbalancedDatasetSamplercSs|S)Nr)rrrr┌<lambda>¬szplot_shap.<locals>.<lambda>)┌sigmoid┌softmaxr-┌binary_threshold┌num_targets┌classify_annotations)rÎrÍÚ
r*TF)┌
batch_size┌num_workers┌shuffle┌sampler┌gradientr-r╦)┌ranked_outputs)r┌┌local_smoothing)r▀┌nsamples)┌axisrcs$g|]}łjłj|ddâddâĹqS)r*rÚ    )┌swapaxes)r%┌s)rrrr&█szplot_shap.<locals>.<listcomp>rm.┌std┌meancs&g|]ëçççfddätłâDâĹqS)cs,g|]$}łdkr łjjł|ntłâĹqS)r*)┌dataset┌targetsr#)r%┌j)┌dataloader_valr'rÎrrr&šsz(plot_shap.<locals>.<listcomp>.<listcomp>)rn)r%)rŰ┌	n_outputsrÎ)r'rr&šsi,)┌dpirŃ)rrrmr*)rrmr*rrŃ)*┌torch┌torch.nnr╬┌numpy┌torch.utils.datar¤┌shap┌pathflowai.datasetsrđ┌
matplotlibrĐZpathflowai.samplerrĎr6rďrŇ┌popZbinarize_annotationsr;rÚ┌next┌iter┌cat┌cuda┌is_available┌detach┌cpuZ
DeepExplainer┌shap_valuesZGradientExplainerrć┌argmaxrńr┐rnr r!r#┌flatten┌figureZ
image_plot┌savefig)$┌model┌dataset_opts┌transform_optsr┌┌outputfilenamerý┌methodrÓ┌	n_samples┌pred_outrţ┌Fr¤r˛rđr˘┌pltrĎZ
out_transformrÍrŔZ	binarizer┌
backgroundZy_background┌X_test┌y_testZmodel2┌erňrř┌idxZ
shap_numpyZX_test_numpyr'Z
test_numpy┌labelsr)rŰrýrrÎr┌	plot_shapůst



.








$

&rš­?š└r@˙output_embedding.pngTrš{«Gßzä?šÜÖÖÖÖÖę?r┘┌ascc
;sţddl}
ddl}ddlm}ddlm}ddlm}ddl}ddl	ëddl
}ddlmëddl
}|jdâddl
m}tjd	d
Źçfddäë|
j|â}|d
}|d}|rŠłj||jâ}|dkrĎ|ddd$ů}|j|}|j|}|Ér|d|kj}|j|}|j|}|Ér:||d|kj}|j|}|j|}|d|
dŹ}|j|j|jddůdd%ůfjâddg|jdŹ}g}xpt|jdâD]^}|j|d}|j|dddgjjâ\}} }!|||||!ů| | |!ůf}"|j|"âÉqŐW|â}#|j|â}|#jâ|Érrddl m!ëm"ëçççfddä}$|j#â\}%}&|$|dj|dj|d|&|	dŹtj$â|j%|ddŹÉnx|jddůdf}'|jddůdf}(çfdd ä|Dâ}t&d!d ä|Dââ})t&d"d ä|Dââ}*|'j'â|'j&â}+},|(j'â|(j&â}-}.|,|+}/|.|-}0|/|0kÉr |/t(|0ât)}1t)}2nt)}1|0t(|/ât)}2łj*|1|)|2|*d#fâ|}3łj+|+|,|1â}4łj+|-|.|2â}5xnt,|'|(|âD]^\}} }6|6jddů\}7}8łj-||4dâ}9łj-| |5dâ}:|6|3|9|9|7ů|:|:|8ůf<ÉqzW|j.j/||3âdS)&a╠Make UMAP embedding plot, overlaid with images.

	Parameters
	----------
	dask_arr_dict:dict
		Stored dask arrays for each WSI.
	embeddings_file:str
		Embeddings pickle file stored from running using after trainign the model.
	ID:str
		Patient ID.
	cval:float
		Deprecated
	image_res:float
		Image resolution.
	outputfname:str
		Output image file.
	mpl_scatter:bool
		Recommended: Use matplotlib for scatter plot.
	remove_background_annotation:str
		Remove the background annotations. Enter for annotation to remove.
	max_background_area:float
		Maximum backgrund area in each tile for inclusion.
	zoom:float
		How much to zoom in on each patch, less than 1 is zoom out.
	n_neighbors:int
		Number of neighbors for UMAP embedding.
	sort_col:str
		Patch info column to sort on.
	sort_mode:str
		Sort ascending or descending.

	Returns
	-------
	type
		Description of returned object.

	Inspired by: https://gist.github.com/lukemetz/be6123c7ee3b366e333a
	WIP!! Needs testing.rN)┌Client)┌UMAP)r)rä┌Agg)rĐr╣)┌stylecsztt|jddůâ\}}t||gâ|krv||krTł|tt|||âât|âfâ}n"ł|t|âtt|||ââfâ}|S)zM
		Resize an image so that it is size along the minimum spatial dimension.
		Nr)┌maprąrć┌minr"┌round)rtr┌w┌h)rärr┌
min_resize$s$"z$plot_umap_images.<locals>.min_resize┌
embeddingsr░┌descr*rśg­?r)┌n_components┌n_neighborsrr
)r»r?rÖ)┌OffsetImage┌AnnotationBboxcsäg}x^tt|ââD]N}||||}}||}	ł|	|dŹ}
ł|
||fdddŹ}|j|j|ââqW|jłj||gââ|jâdS)N)┌zoomrUF)ZxycoordsZframeon)rnr;r3Z
add_artistZupdate_datalim┌column_stack┌	autoscale)rr
┌ax┌	imageDatar(┌imagesr'┌x0┌y0rtr┼┌ab)r'r&rrr┌	imscatterUsz#plot_umap_images.<locals>.imscatter)r,r+r(i,)rÝcsg|]}ł|tâĹqSr)Zimg_res)r%r┼)r!rrr&lsz$plot_umap_images.<locals>.<listcomp>cSsg|]}|jdĹqS)r)rć)r%r┼rrrr&mscSsg|]}|jdĹqS)r*)rć)r%r┼rrrr&nsrmrŃrŃ)0rţ┌dask┌dask.distributedr┌umapr┌pathflowai.visualizer┌pandasr­Z
skimage.ioZskimage.transformrär˘┌userĐr9┌setrŁ┌argsortrArŻrB┌	DataFrame┌
fit_transformr?rnrćr$r3růrźZmatplotlib.offsetboxr&r'┌subplotsZdespiner┌maxrrą┌res┌ones┌linspace┌zip┌argmin┌ioZimsave);r▓┌embeddings_filerś┌cval┌	image_res┌outputfname┌mpl_scatter┌remove_background_annotation┌max_background_arear(r%┌sort_col┌	sort_moderţr2rrrręZskimager˘r
┌embeddings_dictr"r░r┌removal_boolr4┌t_datar-r'rr
rÖrfr(r1r^r+┌xx┌yy┌	max_width┌
max_height┌x_min┌x_max┌y_min┌y_max┌sx┌syZres_xZres_y┌canvasZx_coordsZy_coordsr┼rr ┌x_idxZy_idxr)r'r&r!rrär┌plot_umap_images­sÄ'







0  

"
"r\)rh)rwrx)r*r╦r╠r═F)NrrrTrrrr┘rr)&rb┌plotly.graph_objs┌
graph_objsr4Zplotly.offline┌offliner[r6ręr­rZnetworkx┌nx┌
dask.arrayr rŤ┌PILrr˘┌matplotlib.pyplotrĐr
┌seabornr9rž┌os.pathrr8rrgrlrqrurvrîrŹrr\rrrr┌<module>s.


V


k