@@ -603,26 +603,25 @@ def pictogram_bar(data, title, icon_size, max_icons_per_column=10, units_per_ico
603603 tick_locations = []
604604 # loop through each group and create a trace with its icons
605605 for i, (category, value) in enumerate (data.items()):
606- # compute the number of icons represent this category
606+ # compute the number of icons to use to represent this category. Depending on your use case, you might replace round with floor or ceiling.
607607 icon_count = round (value / units_per_icon)
608- # compute the number of columns in which to arrange this category
609- # every category gets at least one column; we use integer division
610- # to compute the number of additional columns
611- num_columns = (icon_count // max_icons_per_column)+ 1
608+ # compute the number of columns in which to arrange the icons for this category
609+ # using a double negative sign to convert a floor(division) operation into a ceiling(division) operation
610+ num_columns = - (- icon_count // max_icons_per_column)
612611
613- # create lists of coordinates and populate them
612+ # create and populate lists of icon coordinates
614613 x_coordinates, y_coordinates = [], []
615614 for col in range (num_columns):
616615 # the number of icons in this column is the lesser of the column height or
617616 # the number of icons remaining to place
618617 column_icons = min (max_icons_per_column, icon_count - col * max_icons_per_column)
619618
620- # create a list element containing the x-coordinate of this column;
621- # add column_icons copies of that coordinate to the list of icon x coordinates
622- # normalizing the width of each within group column to 1 simplifies the code
623- # we can adjust the visible space between columns by adjusting the total width below
619+ # Create a one item list containing the x-coordinate of this column.
620+ # Then add column_icons copies of that coordinate to the list of icon x coordinates using list multiplication.
621+ # Normalizing the width of each within-category column to 1 simplifies the code.
622+ # We can adjust the visible space between columns by adjusting the total width below.
624623 x_coordinates.extend([x_start + col] * column_icons)
625- # create a list of sequentially increasing y-coordinates for icons
624+ # Create a list of sequentially increasing y-coordinates for icons.
626625 y_coordinates.extend([y + icon_vertical_spacing * y for y in range (1 , column_icons + 1 )])
627626 # Add scatter plot for the category
628627 fig.add_trace(go.Scatter(
@@ -631,43 +630,48 @@ def pictogram_bar(data, title, icon_size, max_icons_per_column=10, units_per_ico
631630 mode = ' markers' ,
632631 marker = dict (size = icon_size, symbol = " square" , color = i),
633632 name = category,
634- # suppress the x and y coordinates in the hover text, since they are meaningless to readers
633+ # Suppress the x and y coordinates in the hover text, since they are irrelevant implementation details.
635634 hoverinfo = " text" ,
636635 text = [f " { category} : { value} " for _ in range (len (x_coordinates))]
637636 ))
638637
639- # add an annotation above the center of each section showing its value
638+ # Add an annotation above the center of each category showing its value
640639 fig.add_trace(go.Scatter(
641- x = [x_start + (num_columns - 1 ) / 2 ], # center
642- y = [max_icons_per_column + 1.2 ],
640+ x = [x_start + (num_columns - 1 ) / 2 ], # Compute the location of the center
641+ y = [max_icons_per_column* ( 1 + icon_vertical_spacing) + 1.15 ],
643642 mode = " text" ,
644643 text = [f " { value} " ],
645644 textfont = dict (size = 14 , color = " black" ),
646645 showlegend = False
647646 ))
648- # Track locations where we will put the text for each category
647+ # Track locations where we will put the text labeling each category
649648 tick_locations.append(x_start + (num_columns - 1 ) / 2 )
650649 # compute the left edge of the next category
651650 x_start += num_columns + inter_group_spacing
652- # Update layout
651+
653652 fig.update_layout(
654653 title = title,
655654 xaxis = dict (
656655 tickvals = tick_locations,
656+ # Label ecah category
657657 ticktext = list (data.keys()),
658658 tickangle = - 45 ,
659659 showgrid = False ,
660660 title = " Categories"
661661 ),
662662 yaxis = dict (
663- title = f " Units (1 icon = { units_per_icon:,g } { unit_description} ) " ,
663+ title = f " Each icon represents { units_per_icon:,g } { unit_description} " ,
664+ # The y-axis goes above the top icon to make room for the annotations.
665+ # We set tick values so the axis labeling does not go above the top icon.
666+ # If you choose a value of max_icons_per_column that is not a multiple of 5, consider changing this.
667+ tickvals = list (range (0 ,max_icons_per_column+ 1 ,5 )),
664668 showgrid = False ,
665669 zeroline = False ,
666670 ),
667- # we've got all the labeling we need without a legend
671+ # We have already got all the labeling we need so we suppress the legend.
668672 showlegend = False ,
669673 height = 700 ,
670- # the x-coordinates scale to fill available space, so adjusting the width of the image is a good way to adjust spacing between columns
674+ # The x-coordinates scale to fill available space, so adjusting the width of the image is a good way to adjust spacing between columns.
671675 width = (len (data) * 150 + 50 )
672676 )
673677 fig.show()
0 commit comments