eaton-lab / toytree

A minimalist tree plotting library using toyplot graphs
http://eaton-lab.org/toytree
BSD 3-Clause "New" or "Revised" License
164 stars 28 forks source link

Shape mismatch using .draw() function #75

Open MauriAndresMU1313 opened 1 year ago

MauriAndresMU1313 commented 1 year ago

I have used this code before without any problems, even though the actual tree which shows me the error now, has been worked on before. Now, that I changed one line to change the information in the tree I have this error with this data frame and tree file. Here is my code:

# Set tree
current_tree_rooted = toytree.tree("7_8_23_group3.treefile")

# Create a new version of the previous tree
current_tree_rooted_v2 = current_tree_rooted

# Define metadata
file_name = "group3_vf5.tsv"

# Creating arrays for the metadata scan
Nodnames = current_tree_rooted_v2.get_tip_labels()
newNodnames = []
newColors = []
data = []

# Counting the tip labels
k = current_tree_rooted_v2.get_tip_labels()
ntips = int(len(k))

# Applying new node labels and storing metada of interest
for aa in k:
    aa = str(aa)
    with open(file_name, 'r') as f_input:
        csv_input = csv.reader(f_input, delimiter='\t', skipinitialspace=False)
        x = []
        y = []
        z = []
        nn = []
        for cols in csv_input:
            x = (str(cols[0]))
            y = (str(cols[1]))
            z = (str(cols[2]))
            if (aa == x):
                newNodnames.append(y)
                #newColors.append(int(z))
                newColors.append(str(z))

# Deducing uniques from the `NewColors` array
# Create a set of unique colors
list_set = set(newColors)
# Convert the set into a list
unique_NewColors = (list(list_set))
# Create empty dictionary and list to store colors
# https://www.color-hex.com/
NRcolor_dict = {
    "1.16.1.7": "#f2d658", # Yellow
    "3.2.1.31": "#89ecda", # White blue
    "3.2.1.4": "#ff1515", # Red
    "5.2.1.8": "#f75956", # Orange
    "3.2.1.35": "#8afe46", # Bright green
    "2.4.1.25": "#61ca9a", # Water green
    "3.2.1.133": "#7f5a83", # Purple opaque
    "3.2.1.52": "#ffa6c9", # Pink
}
v3NewColors = []

# Applying the content in the metadata file (it depends of the previous cell)
for aa in k:
    # Convert variable into string
    aa = str(aa)
    # Read file
    with open(file_name, 'r') as f_input:
        # Create reader objet from metadata file
        csv_input = csv.reader(f_input, delimiter='\t', skipinitialspace=False)
        # Use empty list to store values
        x = []
        nqn = []
        # Iterate over the metadata (each row)
        for cols in csv_input:
            # Add value based on the index (column number)
            x = (str(cols[0]))
            nqn = (str(cols[13]))
            # Check if aa value is equal to x value in the x list
            if (aa == x):
                # Add value to color list
                v3NewColors.append(NRcolor_dict[nqn])

# Creating canvas and creating the tree
# This create a toyplot canvas and cartesian axes to set the dimensions of the phylogenetic tree
canvas = toyplot.Canvas(width=1200, height=2100)
ax0 = canvas.cartesian(bounds=(10, 1000, 50, 2000),
                       padding=15, ymin=0, ymax=ntips)

# Setting node colors only for 100.0 node support
# This line creates a list of colors, where each color is red if the corresponding
# node support is 100.0, and False otherwise
colors = ['red' if ((i) == '100.0') else False for i in
          current_tree_rooted_v2.get_node_values('support', 1, 0)]
# This line creates a list of sizes, where each size is 10 if the corresponding
# node support is 100.0, and 0 otherwise
sizes = [15 if ((i) == '100.0') else 0 for i in
         current_tree_rooted_v2.get_node_values('support', 1, 0)]

# Tree style
style = {
    "tip_labels_align": True,
    "tip_labels_style": {
        "font-size": "12px",
    },
    "edge_style": {
        "stroke": "black",
        "stroke-width": 3,
    },
}

# Creating canvas
current_tree_rooted_v2.draw(
    tip_labels=newNodnames,
    **style,
    node_labels=None,
    node_sizes=sizes,
    node_colors=colors,
    #tip_labels_colors=v3NewColors,
    scalebar=True,
    axes=ax0,
);

# Create and add matrix
# This line creates a matrix of shape `(ntips, 1)`, where each element is
# the index of the corresponding tip in the `newNodnames` list
matrix = np.arange(ntips * 1).reshape(ntips, 1)
matrix.shape

# This line creates a table with `ntips` rows and `1` column
table = canvas.table(
    rows=ntips,
    columns=1,
    margin=0,
    bounds=(1110, 1140, 50, 2000),
)

# Apply a color to each cell in the table
aa = 0
for ridx in range(matrix.shape[0]):
    bb = ntips - aa - 1
    for cidx in range(matrix.shape[1]):
        # This line gets the cell at the specified row and column
        cell = table.cells.cell[ridx, cidx]
        # This line sets the fill color of the cell to the corresponding color in the `v3NewColors` list
        cell.style = {
            "fill": v3NewColors[bb]
        }
        aa = (aa + 1)

# Hides the axes of the cartesian object.
ax0.show = False

# toyplot.pdf.render(canvas, "gh20_group_3_v6.pdf")

The error is this:

ValueError: shape mismatch: objects cannot be broadcast to a single shape.  Mismatch is between arg 0 with shape (128,) and arg 1 with shape (87,).

Specifically, in the line 108:

--> 108 current_tree_rooted_v2.draw(

It seems to me that the issue pop-ups with the .draw() function. Here is a link where I put one of my data, to reproduce the error:

https://github.com/MauriAndresMU1313/Toytree-shape-error

If I check my tree and data frame file (which previously worked fine), I see that everything is correct. Any suggestions on how to fix this issue?