<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 <h2><span style="color
Step1:  Short tutorial
Setup input files and params
Step2:  calculate distances
Step3:  save results
Step4:  Draw the matrix
Step5:  Draw matrix reordered to match groups in imap
<ASSISTANT_TASK:>
Python Code:
# conda install ipyrad -c bioconda
# conda install toyplot -c eaton-lab (optional)
import ipyrad.analysis as ipa
import toyplot
Explanation: <h2><span style="color:gray">ipyrad-analysis toolkit:</span> distance</h2>
Key features:
Calculate pairwise genetic distances between samples. 
Filter SNPs to reduce missing data. 
Impute missing data using population allele frequencies.
required software
End of explanation
# the path to your VCF or HDF5 formatted snps file
data = "/home/deren/Downloads/ref_pop2.snps.hdf5"
# group individuals into populations
imap = {
    "virg": ["TXWV2", "LALC2", "SCCU3", "FLSF33", "FLBA140"],
    "mini": ["FLSF47", "FLMO62", "FLSA185", "FLCK216"],
    "gemi": ["FLCK18", "FLSF54", "FLWO6", "FLAB109"],
    "bran": ["BJSL25", "BJSB3", "BJVL19"],
    "fusi": ["MXED8", "MXGT4", "TXGR3", "TXMD3"],
    "sagr": ["CUVN10", "CUCA4", "CUSV6", "CUMM5"],
    "oleo": ["CRL0030", "CRL0001", "HNDA09", "BZBB1", "MXSA3017"],
}
# minimum n samples that must be present in each SNP from each group
minmap = {i: 0.5 for i in imap}
Explanation: Short tutorial
Setup input files and params
End of explanation
# load the snp data into distance tool with arguments
from ipyrad.analysis.distance import Distance
dist = Distance(
    data=data, 
    imap=imap,
    minmap=minmap,
    mincov=0.5,
    impute_method="sample",
    subsample_snps=False,
)
dist.run()
Explanation: calculate distances
End of explanation
# save to a CSV file
dist.dists.to_csv("distances.csv")
# show the upper corner 
dist.dists.head()
Explanation: save results
End of explanation
toyplot.matrix(
    dist.dists, 
    bshow=False,
    tshow=False,
    rlocator=toyplot.locator.Explicit(
        range(len(dist.names)),
        sorted(dist.names),
));
Explanation: Draw the matrix
End of explanation
# get list of concatenated names from each group
ordered_names = []
for group in dist.imap.values():
    ordered_names += group
# reorder matrix to match name order    
ordered_matrix = dist.dists[ordered_names].T[ordered_names]
toyplot.matrix(
    ordered_matrix,
    bshow=False,
    tshow=False,
    rlocator=toyplot.locator.Explicit(
        range(len(ordered_names)),
        ordered_names,
));
Explanation: Draw matrix reordered to match groups in imap
End of explanation
<END_TASK>