From 4bb0570fd48c5be2bc98ce895dfb394ae9ee3d68 Mon Sep 17 00:00:00 2001 From: Rob Letzler Date: Tue, 24 Dec 2024 22:59:41 -0500 Subject: [PATCH 1/7] Update bar-charts.md --- doc/python/bar-charts.md | 86 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/doc/python/bar-charts.md b/doc/python/bar-charts.md index 9ee75ea440..6fad0f45c2 100644 --- a/doc/python/bar-charts.md +++ b/doc/python/bar-charts.md @@ -589,6 +589,92 @@ fig.update_layout( ) ``` +### Using a scatterplot to wrap long bars into multiple columns + +This bar-style pictogram allows readers to focus on the relative sizes of smaller entities by wrapping the bar for largest entries into multiple columns. You could make it even more of a pictogram by using fontawesome to replace the square markers we use below with icons like mortar boards for students. + +``` +import plotly.graph_objects as go +import pandas as pd + +#TODO: make the results and the code compellingly clear, terse, and well designed; for example, make sure all the variable names are descriptive +#TODO: when we're happy, remove print statements +#TODO: consider adding the value for each group either above its section or to its title + +def pictogram_bar(data, title, icon_size, max_height=10, units_per_icon=1,columns_between_units=.5): + fig = go.Figure() + + # Iterate through the data and create a scatter plot for each category + x_start = 1 + tick_locations = [] + for i, (category, count) in enumerate(data.items()): + #convert the real number input to an integer number of icons. Depending on the context, you might want to take floor or a ceiling rather than rouding + count = round(count / units_per_icon) + num_cols = (count + max_height - 1) // max_height # Ceiling division + x_coordinates = [] + y_coordinates = [] + for col in range(num_cols): + print([x_start+col]*min(max_height, count-col*max_height)) + x_coordinates += [x_start+col]*min(max_height, count-col*max_height) + print(list(range(0, min(max_height, count-col*max_height)))) + for yc in range(1, min(max_height, count-col*max_height)+1): + y_coordinates.append(yc) + print(f"{category=}") + print(f"{x_coordinates=}") + print(f"{y_coordinates=}") + # Add dots for this category + fig.add_trace(go.Scatter( + x=x_coordinates, # All dots are in the same x position (category) + y=y_coordinates, + mode='markers', + marker=dict(size=icon_size, symbol="square", color=i), + name=category, + #text=[category] * (y_end - y_start), # Hover text + hoverinfo="text" + )) + tick_locations += [x_start+ (col)/2] + x_start += col+1+columns_between_units + print(f"{tick_locations=}") + + # Update layout for better visualization + fig.update_layout( + title=title, + xaxis=dict( + tickvals=tick_locations, + ticktext=list(data.keys()), + tickangle=-45, + showgrid=False + ), + #TODO: HIDE THE Y-AXIS? OR ENUMERATE IT IN "NATURAL UNITS" -- so count + yaxis=dict( + title="Units", + showgrid=False, + showline=False, + zeroline=False + ), + #TO DO: SHOW THE LEGEND, BUT JUST FOR ONE TRACE; LABEL IT WITH SOMETHING LIKE "EACH ICON REPRESENTS {units_per_icon} {Y_VARNAME}" + showlegend=False, + #setting the width implicitly sets the amount of space between columns within groups and it's desirable to keep those columns close but not too close + #TODO: set the width to a value that makes the spacing between columns reasonable; try it as a function of the number of columns of data, number of columns left blank as spacers, the icon size; and the left and right margins + # there's no right answer; but some answers will look a lot better than others; I'm guessing that roughly 2-3 times as many px as we fill with icons might be good + height=600 + ) + + # Show the plot + fig.show() + +# TODO: CHANGE THIS THROUGHOUT TO A DF NAMED DF. + +data = { + "Haverford College": 1421, #https://www.usnews.com/best-colleges/haverford-college-3274 + "University of Mary Washington": 3611, #https://www.usnews.com/best-colleges/university-of-mary-washington-3746#:~:text=Overview,campus%20size%20is%20234%20acres. + "Brown University": 7226, #https://oir.brown.edu/institutional-data/factbooks/enrollment + "Arizona State University": 65174, #https://www.usnews.com/best-colleges/arizona-state-university-1081 +} + +pictogram_bar(data, title="Undergraduate Enrollment at Participating Schools", units_per_icon=1000, icon_size=27) +``` + ### Customizing Individual Bar Base ```python From 58ad8b4f92e129ee564afd464a1eb60d7807167c Mon Sep 17 00:00:00 2001 From: Rob Letzler Date: Thu, 2 Jan 2025 23:41:51 -0500 Subject: [PATCH 2/7] Sima's edits to e.g. use a data frame, etc. --- doc/python/bar-charts.md | 106 ++++++++++++++++++++------------------- 1 file changed, 55 insertions(+), 51 deletions(-) diff --git a/doc/python/bar-charts.md b/doc/python/bar-charts.md index 6fad0f45c2..c467af10e7 100644 --- a/doc/python/bar-charts.md +++ b/doc/python/bar-charts.md @@ -597,82 +597,86 @@ This bar-style pictogram allows readers to focus on the relative sizes of smalle import plotly.graph_objects as go import pandas as pd -#TODO: make the results and the code compellingly clear, terse, and well designed; for example, make sure all the variable names are descriptive -#TODO: when we're happy, remove print statements -#TODO: consider adding the value for each group either above its section or to its title - -def pictogram_bar(data, title, icon_size, max_height=10, units_per_icon=1,columns_between_units=.5): - fig = go.Figure() +def pictogram_bar(data, title, icon_size, max_height=10, units_per_icon=1, column_spacing=0.005,icon_spacing=0.005): - # Iterate through the data and create a scatter plot for each category + fig = go.Figure() x_start = 1 tick_locations = [] - for i, (category, count) in enumerate(data.items()): - #convert the real number input to an integer number of icons. Depending on the context, you might want to take floor or a ceiling rather than rouding - count = round(count / units_per_icon) - num_cols = (count + max_height - 1) // max_height # Ceiling division - x_coordinates = [] - y_coordinates = [] - for col in range(num_cols): - print([x_start+col]*min(max_height, count-col*max_height)) - x_coordinates += [x_start+col]*min(max_height, count-col*max_height) - print(list(range(0, min(max_height, count-col*max_height)))) - for yc in range(1, min(max_height, count-col*max_height)+1): - y_coordinates.append(yc) - print(f"{category=}") - print(f"{x_coordinates=}") - print(f"{y_coordinates=}") - # Add dots for this category + + for i, (category, value) in enumerate(data.items()): + icon_count = round(value / units_per_icon) + num_columns = -(-icon_count // max_height) # Ceiling division + + x_coordinates, y_coordinates = [], [] + for col in range(num_columns): + column_icons = min(max_height, icon_count - col * max_height) + x_coordinates.extend([x_start + col] * column_icons) + # y_coordinates.extend(range(1, column_icons + 1)) + y_coordinates.extend([y + icon_spacing * y for y in range(1, column_icons + 1)]) + + + # Add scatter plot for the category fig.add_trace(go.Scatter( - x=x_coordinates, # All dots are in the same x position (category) + x=x_coordinates, y=y_coordinates, mode='markers', - marker=dict(size=icon_size, symbol="square", color=i), + marker=dict(size=icon_size, symbol="square", color= i), name=category, - #text=[category] * (y_end - y_start), # Hover text - hoverinfo="text" + hoverinfo="text", + text=[f"{category}: {value}" for _ in range(len(x_coordinates))] )) - tick_locations += [x_start+ (col)/2] - x_start += col+1+columns_between_units - print(f"{tick_locations=}") - - # Update layout for better visualization + + + # Add value annotations above the section: new line of code + fig.add_trace(go.Scatter( + x=[x_start + (num_columns - 1) / 2], + y=[max_height + 1], + mode="text", + text=[f"{value}"], + textfont=dict(size=14, color="black"), + showlegend=False + )) + + # Track tick locations + tick_locations.append(x_start + (num_columns - 1) / 2) + x_start += num_columns + column_spacing + + # Update layout fig.update_layout( title=title, xaxis=dict( tickvals=tick_locations, ticktext=list(data.keys()), tickangle=-45, - showgrid=False + showgrid=False, + title="Categories" ), - #TODO: HIDE THE Y-AXIS? OR ENUMERATE IT IN "NATURAL UNITS" -- so count yaxis=dict( - title="Units", + title=f"Units (1 icon = {units_per_icon})", showgrid=False, - showline=False, - zeroline=False + zeroline=False, ), - #TO DO: SHOW THE LEGEND, BUT JUST FOR ONE TRACE; LABEL IT WITH SOMETHING LIKE "EACH ICON REPRESENTS {units_per_icon} {Y_VARNAME}" showlegend=False, - #setting the width implicitly sets the amount of space between columns within groups and it's desirable to keep those columns close but not too close - #TODO: set the width to a value that makes the spacing between columns reasonable; try it as a function of the number of columns of data, number of columns left blank as spacers, the icon size; and the left and right margins - # there's no right answer; but some answers will look a lot better than others; I'm guessing that roughly 2-3 times as many px as we fill with icons might be good - height=600 + height=600, + width=(len(data) * 200 + 200) # Done adjused width based on number of categories ) - # Show the plot fig.show() -# TODO: CHANGE THIS THROUGHOUT TO A DF NAMED DF. -data = { - "Haverford College": 1421, #https://www.usnews.com/best-colleges/haverford-college-3274 - "University of Mary Washington": 3611, #https://www.usnews.com/best-colleges/university-of-mary-washington-3746#:~:text=Overview,campus%20size%20is%20234%20acres. - "Brown University": 7226, #https://oir.brown.edu/institutional-data/factbooks/enrollment - "Arizona State University": 65174, #https://www.usnews.com/best-colleges/arizona-state-university-1081 -} +# done as pd +df = pd.DataFrame({ + 'School': ["Haverford College", "University of Mary Washington", "Brown University", "Arizona State University"], + 'Enrollment': [1421, 3611, 7226, 65174] +}) -pictogram_bar(data, title="Undergraduate Enrollment at Participating Schools", units_per_icon=1000, icon_size=27) +pictogram_bar( + data={row['School']: row['Enrollment'] for _, row in df.iterrows()}, + title="Undergraduate Enrollment at Participating Schools", + units_per_icon=1000, + icon_size=27, + icon_spacing=0.05 +) ``` ### Customizing Individual Bar Base From 2ea50a5b318257f515b8d570caae48858f8a7681 Mon Sep 17 00:00:00 2001 From: Rob Letzler Date: Thu, 2 Jan 2025 23:42:54 -0500 Subject: [PATCH 3/7] Rob's edits to e.g. remove the y-axis, generalize sizing, etc. --- doc/python/bar-charts.md | 58 ++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/doc/python/bar-charts.md b/doc/python/bar-charts.md index c467af10e7..06c00c6736 100644 --- a/doc/python/bar-charts.md +++ b/doc/python/bar-charts.md @@ -597,22 +597,24 @@ This bar-style pictogram allows readers to focus on the relative sizes of smalle import plotly.graph_objects as go import pandas as pd -def pictogram_bar(data, title, icon_size, max_height=10, units_per_icon=1, column_spacing=0.005,icon_spacing=0.005): +def pictogram_bar(df, title, icon_size, max_height=10, units_per_icon=1, column_spacing=0.005,icon_spacing=0.005, scale_factor=1.45,description_of_unit = ""): fig = go.Figure() x_start = 1 tick_locations = [] - for i, (category, value) in enumerate(data.items()): + for i, (category, value) in df.iterrows(): icon_count = round(value / units_per_icon) num_columns = -(-icon_count // max_height) # Ceiling division + + x_coordinates, y_coordinates = [], [] for col in range(num_columns): column_icons = min(max_height, icon_count - col * max_height) - x_coordinates.extend([x_start + col] * column_icons) + x_coordinates.extend([(x_start + col)*(1 + icon_spacing)] * column_icons) # y_coordinates.extend(range(1, column_icons + 1)) - y_coordinates.extend([y + icon_spacing * y for y in range(1, column_icons + 1)]) + y_coordinates.extend([(1 + icon_spacing) * y for y in range(2, column_icons + 2)]) # Add scatter plot for the category @@ -621,61 +623,71 @@ def pictogram_bar(data, title, icon_size, max_height=10, units_per_icon=1, colum y=y_coordinates, mode='markers', marker=dict(size=icon_size, symbol="square", color= i), - name=category, hoverinfo="text", - text=[f"{category}: {value}" for _ in range(len(x_coordinates))] + text=[f"{category}: {value}" for _ in range(len(x_coordinates))], + name= f"(1 icon =
{units_per_icon} {description_of_unit})", + showlegend=(i==0) + )) + center_of_category_x = (x_start + (num_columns - 1) / 2)*(1 + icon_spacing) + # Add value annotations above the section: new line of code fig.add_trace(go.Scatter( - x=[x_start + (num_columns - 1) / 2], - y=[max_height + 1], + x=[center_of_category_x], + y=[1],#(max_height+ 1)*(1 + icon_spacing) mode="text", - text=[f"{value}"], + text=[f"{value:,.0f}"], textfont=dict(size=14, color="black"), - showlegend=False + showlegend=False, )) # Track tick locations - tick_locations.append(x_start + (num_columns - 1) / 2) + tick_locations.append(center_of_category_x) x_start += num_columns + column_spacing + print(x_start) # Update layout fig.update_layout( title=title, xaxis=dict( + #range=[0,x_start], tickvals=tick_locations, - ticktext=list(data.keys()), + ticktext=list(df.keys()), tickangle=-45, showgrid=False, - title="Categories" ), yaxis=dict( - title=f"Units (1 icon = {units_per_icon})", - showgrid=False, - zeroline=False, + visible= False, + #scaleanchor = "x", + #scaleratio = 1, ), - showlegend=False, - height=600, - width=(len(data) * 200 + 200) # Done adjused width based on number of categories + + legend=dict( #this works best with the big category last, so there will be typically space for a legend in the lower right + yanchor="top", + y=-0.1, + xanchor="right", + x=1), + height=(max_height * (icon_size*(1+icon_spacing)*scale_factor) + 200), #we care about the ratio of the icon size measured in PX to the size of the plot area, so + width=(x_start * (icon_size*(1+icon_spacing)*scale_factor) + 100) # Done adjusted width based on number of categories ) fig.show() -# done as pd df = pd.DataFrame({ 'School': ["Haverford College", "University of Mary Washington", "Brown University", "Arizona State University"], 'Enrollment': [1421, 3611, 7226, 65174] }) pictogram_bar( - data={row['School']: row['Enrollment'] for _, row in df.iterrows()}, + df, title="Undergraduate Enrollment at Participating Schools", units_per_icon=1000, - icon_size=27, - icon_spacing=0.05 + icon_size=20, + icon_spacing=0.7, + description_of_unit="students" ) ``` From 35bf72d3e67e14038d3f9d36fde2571d63153b1c Mon Sep 17 00:00:00 2001 From: Rob Letzler Date: Thu, 2 Jan 2025 23:44:41 -0500 Subject: [PATCH 4/7] added collaboration scratchwork notebook --- doc/python/plotly-universities-1.ipynb | 1360 ++++++++++++++++++++++++ 1 file changed, 1360 insertions(+) create mode 100644 doc/python/plotly-universities-1.ipynb diff --git a/doc/python/plotly-universities-1.ipynb b/doc/python/plotly-universities-1.ipynb new file mode 100644 index 0000000000..f638614af9 --- /dev/null +++ b/doc/python/plotly-universities-1.ipynb @@ -0,0 +1,1360 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "plotlyServerURL": "https://plot.ly" + }, + "data": [ + { + "hoverinfo": "text", + "marker": { + "color": 0, + "size": 27, + "symbol": "square" + }, + "mode": "markers", + "name": "Haverford College", + "text": [ + "Haverford College: 1421" + ], + "type": "scatter", + "x": [ + 1 + ], + "y": [ + 2 + ] + }, + { + "mode": "text", + "showlegend": false, + "text": [ + "1421" + ], + "textfont": { + "color": "black", + "size": 14 + }, + "type": "scatter", + "x": [ + 1 + ], + "y": [ + 11 + ] + }, + { + "hoverinfo": "text", + "marker": { + "color": 1, + "size": 27, + "symbol": "square" + }, + "mode": "markers", + "name": "University of Mary Washington", + "text": [ + "University of Mary Washington: 3611", + "University of Mary Washington: 3611", + "University of Mary Washington: 3611", + "University of Mary Washington: 3611" + ], + "type": "scatter", + "x": [ + 2.005, + 2.005, + 2.005, + 2.005 + ], + "y": [ + 2, + 4, + 6, + 8 + ] + }, + { + "mode": "text", + "showlegend": false, + "text": [ + "3611" + ], + "textfont": { + "color": "black", + "size": 14 + }, + "type": "scatter", + "x": [ + 2.005 + ], + "y": [ + 11 + ] + }, + { + "hoverinfo": "text", + "marker": { + "color": 2, + "size": 27, + "symbol": "square" + }, + "mode": "markers", + "name": "Brown University", + "text": [ + "Brown University: 7226", + "Brown University: 7226", + "Brown University: 7226", + "Brown University: 7226", + "Brown University: 7226", + "Brown University: 7226", + "Brown University: 7226" + ], + "type": "scatter", + "x": [ + 3.01, + 3.01, + 3.01, + 3.01, + 3.01, + 3.01, + 3.01 + ], + "y": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14 + ] + }, + { + "mode": "text", + "showlegend": false, + "text": [ + "7226" + ], + "textfont": { + "color": "black", + "size": 14 + }, + "type": "scatter", + "x": [ + 3.01 + ], + "y": [ + 11 + ] + }, + { + "hoverinfo": "text", + "marker": { + "color": 3, + "size": 27, + "symbol": "square" + }, + "mode": "markers", + "name": "Arizona State University", + "text": [ + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174", + "Arizona State University: 65174" + ], + "type": "scatter", + "x": [ + 4.015, + 4.015, + 4.015, + 4.015, + 4.015, + 4.015, + 4.015, + 4.015, + 4.015, + 4.015, + 5.015, + 5.015, + 5.015, + 5.015, + 5.015, + 5.015, + 5.015, + 5.015, + 5.015, + 5.015, + 6.015, + 6.015, + 6.015, + 6.015, + 6.015, + 6.015, + 6.015, + 6.015, + 6.015, + 6.015, + 7.015, + 7.015, + 7.015, + 7.015, + 7.015, + 7.015, + 7.015, + 7.015, + 7.015, + 7.015, + 8.015, + 8.015, + 8.015, + 8.015, + 8.015, + 8.015, + 8.015, + 8.015, + 8.015, + 8.015, + 9.015, + 9.015, + 9.015, + 9.015, + 9.015, + 9.015, + 9.015, + 9.015, + 9.015, + 9.015, + 10.015, + 10.015, + 10.015, + 10.015, + 10.015 + ], + "y": [ + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 2, + 4, + 6, + 8, + 10 + ] + }, + { + "mode": "text", + "showlegend": false, + "text": [ + "65174" + ], + "textfont": { + "color": "black", + "size": 14 + }, + "type": "scatter", + "x": [ + 7.015 + ], + "y": [ + 11 + ] + } + ], + "layout": { + "height": 600, + "showlegend": false, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + }, + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "pattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "fillpattern": { + "fillmode": "overlay", + "size": 10, + "solidity": 0.2 + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "autotypenumbers": "strict", + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Undergraduate Enrollment at Participating Schools" + }, + "width": 1000, + "xaxis": { + "showgrid": false, + "tickangle": -45, + "ticktext": [ + "Haverford College", + "University of Mary Washington", + "Brown University", + "Arizona State University" + ], + "tickvals": [ + 1, + 2.005, + 3.01, + 7.015 + ], + "title": { + "text": "Categories" + } + }, + "yaxis": { + "showgrid": false, + "title": { + "text": "Units (1 icon = 1000)" + }, + "zeroline": false + } + } + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import plotly.graph_objects as go\n", + "import pandas as pd\n", + "\n", + "def pictogram_bar(data, title, icon_size, max_height=10, units_per_icon=1, column_spacing=0.005,icon_spacing=0.005):\n", + " \n", + " fig = go.Figure()\n", + " x_start = 1\n", + " tick_locations = []\n", + "\n", + " for i, (category, value) in enumerate(data.items()):\n", + " icon_count = round(value / units_per_icon)\n", + " num_columns = -(-icon_count // max_height) # Ceiling division\n", + "\n", + " x_coordinates, y_coordinates = [], []\n", + " for col in range(num_columns):\n", + " column_icons = min(max_height, icon_count - col * max_height)\n", + " x_coordinates.extend([x_start + col] * column_icons)\n", + " # y_coordinates.extend(range(1, column_icons + 1))\n", + " y_coordinates.extend([(1 + icon_spacing) * y for y in range(1, column_icons + 1)])\n", + "\n", + "\n", + " # Add scatter plot for the category\n", + " fig.add_trace(go.Scatter(\n", + " x=x_coordinates,\n", + " y=y_coordinates,\n", + " mode='markers',\n", + " marker=dict(size=icon_size, symbol=\"square\", color= i),\n", + " name=category,\n", + " hoverinfo=\"text\",\n", + " text=[f\"{category}: {value}\" for _ in range(len(x_coordinates))]\n", + " ))\n", + " \n", + "\n", + " # Add value annotations above the section: new line of code \n", + " fig.add_trace(go.Scatter(\n", + " x=[x_start + (num_columns - 1) / 2],\n", + " y=[max_height + 1],\n", + " mode=\"text\",\n", + " text=[f\"{value}\"],\n", + " textfont=dict(size=14, color=\"black\"),\n", + " showlegend=False\n", + " ))\n", + "\n", + " # Track tick locations\n", + " tick_locations.append(x_start + (num_columns - 1) / 2)\n", + " x_start += num_columns + column_spacing\n", + "\n", + " # Update layout\n", + " fig.update_layout(\n", + " title=title,\n", + " xaxis=dict(\n", + " tickvals=tick_locations,\n", + " ticktext=list(data.keys()),\n", + " tickangle=-45,\n", + " showgrid=False,\n", + " title=\"Categories\"\n", + " ),\n", + " yaxis=dict(\n", + " title=f\"Units (1 icon = {units_per_icon})\",\n", + " showgrid=False,\n", + " zeroline=False,\n", + " ),\n", + " showlegend=False,\n", + " height=600,\n", + " width=(len(data) * 200 + 200) # Done adjused width based on number of categories\n", + " )\n", + "\n", + " fig.show()\n", + "\n", + "\n", + "# done as pd \n", + "df = pd.DataFrame({\n", + " 'School': [\"Haverford College\", \"University of Mary Washington\", \"Brown University\", \"Arizona State University\"],\n", + " 'Enrollment': [1421, 3611, 7226, 65174]\n", + "})\n", + "\n", + "pictogram_bar(\n", + " data={row['School']: row['Enrollment'] for _, row in df.iterrows()},\n", + " title=\"Undergraduate Enrollment at Participating Schools\",\n", + " units_per_icon=1000,\n", + " icon_size=27,\n", + " icon_spacing=0.3\n", + ")\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "anaconda_312", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From f80c36560f8da110c4e4381d98e5c9036a462f51 Mon Sep 17 00:00:00 2001 From: Rob Letzler Date: Fri, 3 Jan 2025 00:05:08 -0500 Subject: [PATCH 5/7] fixed a bug in the category names --- doc/python/plotly-universities-1.ipynb | 497 ++++++++++++++----------- 1 file changed, 283 insertions(+), 214 deletions(-) diff --git a/doc/python/plotly-universities-1.ipynb b/doc/python/plotly-universities-1.ipynb index f638614af9..b651098ef4 100644 --- a/doc/python/plotly-universities-1.ipynb +++ b/doc/python/plotly-universities-1.ipynb @@ -2,9 +2,16 @@ "cells": [ { "cell_type": "code", - "execution_count": 2, + "execution_count": 67, "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "11.02\n" + ] + }, { "data": { "application/vnd.plotly.v1+json": { @@ -16,27 +23,28 @@ "hoverinfo": "text", "marker": { "color": 0, - "size": 27, + "size": 20, "symbol": "square" }, "mode": "markers", - "name": "Haverford College", + "name": "(1 icon =
1000 students)", + "showlegend": true, "text": [ "Haverford College: 1421" ], "type": "scatter", "x": [ - 1 + 1.7 ], "y": [ - 2 + 3.4 ] }, { "mode": "text", "showlegend": false, "text": [ - "1421" + "1,421" ], "textfont": { "color": "black", @@ -44,21 +52,22 @@ }, "type": "scatter", "x": [ - 1 + 1.7 ], "y": [ - 11 + 1 ] }, { "hoverinfo": "text", "marker": { "color": 1, - "size": 27, + "size": 20, "symbol": "square" }, "mode": "markers", - "name": "University of Mary Washington", + "name": "(1 icon =
1000 students)", + "showlegend": false, "text": [ "University of Mary Washington: 3611", "University of Mary Washington: 3611", @@ -67,23 +76,23 @@ ], "type": "scatter", "x": [ - 2.005, - 2.005, - 2.005, - 2.005 + 3.4084999999999996, + 3.4084999999999996, + 3.4084999999999996, + 3.4084999999999996 ], "y": [ - 2, - 4, - 6, - 8 + 3.4, + 5.1, + 6.8, + 8.5 ] }, { "mode": "text", "showlegend": false, "text": [ - "3611" + "3,611" ], "textfont": { "color": "black", @@ -91,21 +100,22 @@ }, "type": "scatter", "x": [ - 2.005 + 3.4084999999999996 ], "y": [ - 11 + 1 ] }, { "hoverinfo": "text", "marker": { "color": 2, - "size": 27, + "size": 20, "symbol": "square" }, "mode": "markers", - "name": "Brown University", + "name": "(1 icon =
1000 students)", + "showlegend": false, "text": [ "Brown University: 7226", "Brown University: 7226", @@ -117,29 +127,29 @@ ], "type": "scatter", "x": [ - 3.01, - 3.01, - 3.01, - 3.01, - 3.01, - 3.01, - 3.01 + 5.116999999999999, + 5.116999999999999, + 5.116999999999999, + 5.116999999999999, + 5.116999999999999, + 5.116999999999999, + 5.116999999999999 ], "y": [ - 2, - 4, - 6, - 8, - 10, - 12, - 14 + 3.4, + 5.1, + 6.8, + 8.5, + 10.2, + 11.9, + 13.6 ] }, { "mode": "text", "showlegend": false, "text": [ - "7226" + "7,226" ], "textfont": { "color": "black", @@ -147,21 +157,22 @@ }, "type": "scatter", "x": [ - 3.01 + 5.116999999999999 ], "y": [ - 11 + 1 ] }, { "hoverinfo": "text", "marker": { "color": 3, - "size": 27, + "size": 20, "symbol": "square" }, "mode": "markers", - "name": "Arizona State University", + "name": "(1 icon =
1000 students)", + "showlegend": false, "text": [ "Arizona State University: 65174", "Arizona State University: 65174", @@ -231,145 +242,145 @@ ], "type": "scatter", "x": [ - 4.015, - 4.015, - 4.015, - 4.015, - 4.015, - 4.015, - 4.015, - 4.015, - 4.015, - 4.015, - 5.015, - 5.015, - 5.015, - 5.015, - 5.015, - 5.015, - 5.015, - 5.015, - 5.015, - 5.015, - 6.015, - 6.015, - 6.015, - 6.015, - 6.015, - 6.015, - 6.015, - 6.015, - 6.015, - 6.015, - 7.015, - 7.015, - 7.015, - 7.015, - 7.015, - 7.015, - 7.015, - 7.015, - 7.015, - 7.015, - 8.015, - 8.015, - 8.015, - 8.015, - 8.015, - 8.015, - 8.015, - 8.015, - 8.015, - 8.015, - 9.015, - 9.015, - 9.015, - 9.015, - 9.015, - 9.015, - 9.015, - 9.015, - 9.015, - 9.015, - 10.015, - 10.015, - 10.015, - 10.015, - 10.015 + 6.825499999999999, + 6.825499999999999, + 6.825499999999999, + 6.825499999999999, + 6.825499999999999, + 6.825499999999999, + 6.825499999999999, + 6.825499999999999, + 6.825499999999999, + 6.825499999999999, + 8.5255, + 8.5255, + 8.5255, + 8.5255, + 8.5255, + 8.5255, + 8.5255, + 8.5255, + 8.5255, + 8.5255, + 10.225499999999998, + 10.225499999999998, + 10.225499999999998, + 10.225499999999998, + 10.225499999999998, + 10.225499999999998, + 10.225499999999998, + 10.225499999999998, + 10.225499999999998, + 10.225499999999998, + 11.9255, + 11.9255, + 11.9255, + 11.9255, + 11.9255, + 11.9255, + 11.9255, + 11.9255, + 11.9255, + 11.9255, + 13.6255, + 13.6255, + 13.6255, + 13.6255, + 13.6255, + 13.6255, + 13.6255, + 13.6255, + 13.6255, + 13.6255, + 15.3255, + 15.3255, + 15.3255, + 15.3255, + 15.3255, + 15.3255, + 15.3255, + 15.3255, + 15.3255, + 15.3255, + 17.0255, + 17.0255, + 17.0255, + 17.0255, + 17.0255 ], "y": [ - 2, - 4, - 6, - 8, - 10, - 12, - 14, - 16, - 18, - 20, - 2, - 4, - 6, - 8, - 10, - 12, - 14, - 16, - 18, - 20, - 2, - 4, - 6, - 8, - 10, - 12, - 14, - 16, - 18, - 20, - 2, - 4, - 6, - 8, - 10, - 12, - 14, - 16, - 18, - 20, - 2, - 4, - 6, - 8, - 10, - 12, - 14, - 16, - 18, - 20, - 2, - 4, - 6, - 8, - 10, - 12, - 14, - 16, - 18, - 20, - 2, - 4, - 6, - 8, - 10 + 3.4, + 5.1, + 6.8, + 8.5, + 10.2, + 11.9, + 13.6, + 15.299999999999999, + 17, + 18.7, + 3.4, + 5.1, + 6.8, + 8.5, + 10.2, + 11.9, + 13.6, + 15.299999999999999, + 17, + 18.7, + 3.4, + 5.1, + 6.8, + 8.5, + 10.2, + 11.9, + 13.6, + 15.299999999999999, + 17, + 18.7, + 3.4, + 5.1, + 6.8, + 8.5, + 10.2, + 11.9, + 13.6, + 15.299999999999999, + 17, + 18.7, + 3.4, + 5.1, + 6.8, + 8.5, + 10.2, + 11.9, + 13.6, + 15.299999999999999, + 17, + 18.7, + 3.4, + 5.1, + 6.8, + 8.5, + 10.2, + 11.9, + 13.6, + 15.299999999999999, + 17, + 18.7, + 3.4, + 5.1, + 6.8, + 8.5, + 10.2 ] }, { "mode": "text", "showlegend": false, "text": [ - "65174" + "65,174" ], "textfont": { "color": "black", @@ -377,16 +388,21 @@ }, "type": "scatter", "x": [ - 7.015 + 11.9255 ], "y": [ - 11 + 1 ] } ], "layout": { - "height": 600, - "showlegend": false, + "height": 693, + "legend": { + "x": 1, + "xanchor": "right", + "y": -0.1, + "yanchor": "top" + }, "template": { "data": { "bar": [ @@ -1206,7 +1222,7 @@ "title": { "text": "Undergraduate Enrollment at Participating Schools" }, - "width": 1000, + "width": 643.286, "xaxis": { "showgrid": false, "tickangle": -45, @@ -1217,21 +1233,14 @@ "Arizona State University" ], "tickvals": [ - 1, - 2.005, - 3.01, - 7.015 - ], - "title": { - "text": "Categories" - } + 1.7, + 3.4084999999999996, + 5.116999999999999, + 11.9255 + ] }, "yaxis": { - "showgrid": false, - "title": { - "text": "Units (1 icon = 1000)" - }, - "zeroline": false + "visible": false } } } @@ -1244,22 +1253,24 @@ "import plotly.graph_objects as go\n", "import pandas as pd\n", "\n", - "def pictogram_bar(data, title, icon_size, max_height=10, units_per_icon=1, column_spacing=0.005,icon_spacing=0.005):\n", + "def pictogram_bar(df, title, icon_size, max_height=10, units_per_icon=1, column_spacing=0.005,icon_spacing=0.005, scale_factor=1.45,description_of_unit = \"\"):\n", " \n", " fig = go.Figure()\n", " x_start = 1\n", " tick_locations = []\n", "\n", - " for i, (category, value) in enumerate(data.items()):\n", + " for i, (category, value) in df.iterrows():\n", " icon_count = round(value / units_per_icon)\n", " num_columns = -(-icon_count // max_height) # Ceiling division\n", "\n", + " \n", + " \n", " x_coordinates, y_coordinates = [], []\n", " for col in range(num_columns):\n", " column_icons = min(max_height, icon_count - col * max_height)\n", - " x_coordinates.extend([x_start + col] * column_icons)\n", + " x_coordinates.extend([(x_start + col)*(1 + icon_spacing)] * column_icons)\n", " # y_coordinates.extend(range(1, column_icons + 1))\n", - " y_coordinates.extend([(1 + icon_spacing) * y for y in range(1, column_icons + 1)])\n", + " y_coordinates.extend([(1 + icon_spacing) * y for y in range(2, column_icons + 2)])\n", "\n", "\n", " # Add scatter plot for the category\n", @@ -1268,61 +1279,71 @@ " y=y_coordinates,\n", " mode='markers',\n", " marker=dict(size=icon_size, symbol=\"square\", color= i),\n", - " name=category,\n", " hoverinfo=\"text\",\n", - " text=[f\"{category}: {value}\" for _ in range(len(x_coordinates))]\n", + " text=[f\"{category}: {value}\" for _ in range(len(x_coordinates))],\n", + " name= f\"(1 icon =
{units_per_icon} {description_of_unit})\",\n", + " showlegend=(i==0)\n", + "\n", " ))\n", " \n", "\n", + " center_of_category_x = (x_start + (num_columns - 1) / 2)*(1 + icon_spacing)\n", + "\n", " # Add value annotations above the section: new line of code \n", " fig.add_trace(go.Scatter(\n", - " x=[x_start + (num_columns - 1) / 2],\n", - " y=[max_height + 1],\n", + " x=[center_of_category_x],\n", + " y=[1],#(max_height+ 1)*(1 + icon_spacing) \n", " mode=\"text\",\n", - " text=[f\"{value}\"],\n", + " text=[f\"{value:,.0f}\"],\n", " textfont=dict(size=14, color=\"black\"),\n", - " showlegend=False\n", + " showlegend=False,\n", " ))\n", "\n", " # Track tick locations\n", - " tick_locations.append(x_start + (num_columns - 1) / 2)\n", + " tick_locations.append(center_of_category_x)\n", " x_start += num_columns + column_spacing\n", "\n", + " print(x_start)\n", " # Update layout\n", " fig.update_layout(\n", " title=title,\n", " xaxis=dict(\n", + " #range=[0,x_start],\n", " tickvals=tick_locations,\n", - " ticktext=list(data.keys()),\n", + " ticktext=list(df[df.columns[0]]),\n", " tickangle=-45,\n", " showgrid=False,\n", - " title=\"Categories\"\n", " ),\n", " yaxis=dict(\n", - " title=f\"Units (1 icon = {units_per_icon})\",\n", - " showgrid=False,\n", - " zeroline=False,\n", + " visible= False,\n", + " #scaleanchor = \"x\",\n", + " #scaleratio = 1,\n", " ),\n", - " showlegend=False,\n", - " height=600,\n", - " width=(len(data) * 200 + 200) # Done adjused width based on number of categories\n", + " \n", + " legend=dict( #this works best with the big category last, so there will be typically space for a legend in the lower right\n", + " yanchor=\"top\",\n", + " y=-0.1,\n", + " xanchor=\"right\",\n", + " x=1),\n", + " height=(max_height * (icon_size*(1+icon_spacing)*scale_factor) + 200), #we care about the ratio of the icon size measured in PX to the size of the plot area, so \n", + " width=(x_start * (icon_size*(1+icon_spacing)*scale_factor) + 100) # Done adjusted width based on number of categories\n", " )\n", "\n", " fig.show()\n", "\n", "\n", - "# done as pd \n", "df = pd.DataFrame({\n", " 'School': [\"Haverford College\", \"University of Mary Washington\", \"Brown University\", \"Arizona State University\"],\n", " 'Enrollment': [1421, 3611, 7226, 65174]\n", "})\n", "\n", "pictogram_bar(\n", - " data={row['School']: row['Enrollment'] for _, row in df.iterrows()},\n", + " df,\n", " title=\"Undergraduate Enrollment at Participating Schools\",\n", " units_per_icon=1000,\n", - " icon_size=27,\n", - " icon_spacing=0.3\n", + " icon_size=20,\n", + " icon_spacing=0.7,\n", + " description_of_unit=\"students\"\n", ")\n", "\n", "\n" @@ -1334,6 +1355,54 @@ "source": [ "\n" ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'x_start' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[51], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(x_start)\n", + "\u001b[1;31mNameError\u001b[0m: name 'x_start' is not defined" + ] + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 66, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0 Haverford College\n", + "1 University of Mary Washington\n", + "2 Brown University\n", + "3 Arizona State University\n", + "Name: School, dtype: object" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { From d2285ad5baa00c8ab28ecb9260c9e1ee8c798e13 Mon Sep 17 00:00:00 2001 From: Rob Letzler Date: Thu, 9 Jan 2025 23:22:29 -0500 Subject: [PATCH 6/7] commented the code; added cross reference --- doc/python/bar-charts.md | 91 ++++---- doc/python/line-and-scatter.md | 4 + doc/python/plotly-universities-1.ipynb | 306 ++++++++++++------------- 3 files changed, 198 insertions(+), 203 deletions(-) diff --git a/doc/python/bar-charts.md b/doc/python/bar-charts.md index 06c00c6736..96fd68f092 100644 --- a/doc/python/bar-charts.md +++ b/doc/python/bar-charts.md @@ -589,54 +589,73 @@ fig.update_layout( ) ``` -### Using a scatterplot to wrap long bars into multiple columns +### Clarifying the size of smaller categories by wrapping the largest bars -This bar-style pictogram allows readers to focus on the relative sizes of smaller entities by wrapping the bar for largest entries into multiple columns. You could make it even more of a pictogram by using fontawesome to replace the square markers we use below with icons like mortar boards for students. +This bar-style pictogram clearly presents the relative sizes of smaller entities by wrapping the bar for the largest entry into multiple columns. The clarity about the size of the smaller entities comes at the cost of reduced clarity about the wrapped entry. It also rounds values so they can be represented with a whole number of icons. You could make it even more of a pictogram by using Font Awesome to replace the square markers we use below with icons like mortar boards for students. ``` import plotly.graph_objects as go import pandas as pd - -def pictogram_bar(df, title, icon_size, max_height=10, units_per_icon=1, column_spacing=0.005,icon_spacing=0.005, scale_factor=1.45,description_of_unit = ""): - +import math + +def pictogram_bar(df, + x, # string containing the column name of the categories + y, # string containing the column name of the values + title="", # title of the figure + icon_size=25, # icon size in px + max_icons_per_column=10, + units_per_icon=1, + column_spacing=0.005, + spacing_between_categories=1, # horizontal blank space between categories + icon_spacing=0.005, + scale_factor=1.45, #higher values of this move icons farther apart and make the graph bigger + description_of_unit="" # text for the legend, which contains + # "(1 icon =
{units_per_icon} {description_of_unit})" +): fig = go.Figure() - x_start = 1 + x_coordinate_of_left_edge_of_group = 1 tick_locations = [] - for i, (category, value) in df.iterrows(): - icon_count = round(value / units_per_icon) - num_columns = -(-icon_count // max_height) # Ceiling division - - - - x_coordinates, y_coordinates = [], [] + # iterate through each category with its name in the x column and its value in the y column + # in the data and generate lists of X coordinates and Y coordinates to visualize its value + # in the form of icons in a single, vertical bar if its value is less than units_per_icon * max_icons_per_column + # and in the form of multiple columns of icons if its value is greater than that + for i, row in df.iterrows(): + category=row[x] + value = row[y] + icon_count = round(value / units_per_icon) # compute the number of icons needed to represent value + num_columns = math.ceil(icon_count / max_icons_per_column) # compute the number of columns we'll arrange them into + + #generate list of x and y coordinates for the icons representing this category + x_coordinates = [] + y_coordinates = [] for col in range(num_columns): - column_icons = min(max_height, icon_count - col * max_height) - x_coordinates.extend([(x_start + col)*(1 + icon_spacing)] * column_icons) - # y_coordinates.extend(range(1, column_icons + 1)) + column_icons = min(max_icons_per_column, icon_count - col * max_icons_per_column) + x_coordinates.extend([(x_coordinate_of_left_edge_of_group + col)*(1 + icon_spacing)] * column_icons) y_coordinates.extend([(1 + icon_spacing) * y for y in range(2, column_icons + 2)]) - # Add scatter plot for the category + # Add scatter plot trace for the current category fig.add_trace(go.Scatter( x=x_coordinates, y=y_coordinates, mode='markers', marker=dict(size=icon_size, symbol="square", color= i), hoverinfo="text", + #make one label for each icon in this category text=[f"{category}: {value}" for _ in range(len(x_coordinates))], name= f"(1 icon =
{units_per_icon} {description_of_unit})", showlegend=(i==0) )) - - center_of_category_x = (x_start + (num_columns - 1) / 2)*(1 + icon_spacing) - - # Add value annotations above the section: new line of code + # compute the x coordinate where we'll label this category + center_of_category_x = (x_coordinate_of_left_edge_of_group + (num_columns - 1) / 2)*(1 + icon_spacing) + + # Add the numeric values for each category underneath the category's icons fig.add_trace(go.Scatter( x=[center_of_category_x], - y=[1],#(max_height+ 1)*(1 + icon_spacing) + y=[1],#(max_icons_per_column+ 1)*(1 + icon_spacing) mode="text", text=[f"{value:,.0f}"], textfont=dict(size=14, color="black"), @@ -645,34 +664,32 @@ def pictogram_bar(df, title, icon_size, max_height=10, units_per_icon=1, column_ # Track tick locations tick_locations.append(center_of_category_x) - x_start += num_columns + column_spacing + x_coordinate_of_left_edge_of_group += num_columns + column_spacing + spacing_between_categories - print(x_start) - # Update layout fig.update_layout( title=title, xaxis=dict( - #range=[0,x_start], tickvals=tick_locations, - ticktext=list(df.keys()), + ticktext=list(df[x]), tickangle=-45, showgrid=False, ), + # hide the y-axis yaxis=dict( visible= False, - #scaleanchor = "x", - #scaleratio = 1, ), - legend=dict( #this works best with the big category last, so there will be typically space for a legend in the lower right + # put the legend in the lower right, on the assumption that it's the biggest category which left a space + legend=dict( yanchor="top", y=-0.1, xanchor="right", x=1), - height=(max_height * (icon_size*(1+icon_spacing)*scale_factor) + 200), #we care about the ratio of the icon size measured in PX to the size of the plot area, so - width=(x_start * (icon_size*(1+icon_spacing)*scale_factor) + 100) # Done adjusted width based on number of categories + # we specify the plot area size because care about the ratio of the icon size to the size of the plot area + height=(max_icons_per_column * (icon_size*(1+icon_spacing)*scale_factor) + 200), + width=((x_coordinate_of_left_edge_of_group-spacing_between_categories) #subtract to remove spacing between categories to the right of the final category + * (icon_size*(1+icon_spacing)*scale_factor) + 100) ) - fig.show() @@ -682,13 +699,9 @@ df = pd.DataFrame({ }) pictogram_bar( - df, + df, x='School', y='Enrollment', title="Undergraduate Enrollment at Participating Schools", - units_per_icon=1000, - icon_size=20, - icon_spacing=0.7, - description_of_unit="students" -) + units_per_icon=1000, icon_size=20, icon_spacing=0.7, spacing_between_categories = 0.6, description_of_unit="students" ) ``` ### Customizing Individual Bar Base diff --git a/doc/python/line-and-scatter.md b/doc/python/line-and-scatter.md index 802f622417..1512d19d2b 100644 --- a/doc/python/line-and-scatter.md +++ b/doc/python/line-and-scatter.md @@ -426,6 +426,10 @@ fig = go.Figure(data=go.Scatter( fig.show() ``` +#### Using a scatter plot to create a bar-style pictograph + +An [example in the bar chart documentation](/python/bar-charts/#clarifying-the-size-of-smaller-categories-by-wrapping-the-largest-bars) uses scatter traces to create a bar-style pictograph that clarifies the relative sizes of entities with radically different sizes and demonstrates the versatility of the scatter trace. + #### Trace Zorder *New in 5.21* diff --git a/doc/python/plotly-universities-1.ipynb b/doc/python/plotly-universities-1.ipynb index b651098ef4..345c7a1ce8 100644 --- a/doc/python/plotly-universities-1.ipynb +++ b/doc/python/plotly-universities-1.ipynb @@ -2,14 +2,14 @@ "cells": [ { "cell_type": "code", - "execution_count": 67, + "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "11.02\n" + "13.419999999999998\n" ] }, { @@ -76,10 +76,10 @@ ], "type": "scatter", "x": [ - 3.4084999999999996, - 3.4084999999999996, - 3.4084999999999996, - 3.4084999999999996 + 4.4285, + 4.4285, + 4.4285, + 4.4285 ], "y": [ 3.4, @@ -100,7 +100,7 @@ }, "type": "scatter", "x": [ - 3.4084999999999996 + 4.4285 ], "y": [ 1 @@ -127,13 +127,13 @@ ], "type": "scatter", "x": [ - 5.116999999999999, - 5.116999999999999, - 5.116999999999999, - 5.116999999999999, - 5.116999999999999, - 5.116999999999999, - 5.116999999999999 + 7.157, + 7.157, + 7.157, + 7.157, + 7.157, + 7.157, + 7.157 ], "y": [ 3.4, @@ -157,7 +157,7 @@ }, "type": "scatter", "x": [ - 5.116999999999999 + 7.157 ], "y": [ 1 @@ -242,71 +242,71 @@ ], "type": "scatter", "x": [ - 6.825499999999999, - 6.825499999999999, - 6.825499999999999, - 6.825499999999999, - 6.825499999999999, - 6.825499999999999, - 6.825499999999999, - 6.825499999999999, - 6.825499999999999, - 6.825499999999999, - 8.5255, - 8.5255, - 8.5255, - 8.5255, - 8.5255, - 8.5255, - 8.5255, - 8.5255, - 8.5255, - 8.5255, - 10.225499999999998, - 10.225499999999998, - 10.225499999999998, - 10.225499999999998, - 10.225499999999998, - 10.225499999999998, - 10.225499999999998, - 10.225499999999998, - 10.225499999999998, - 10.225499999999998, - 11.9255, - 11.9255, - 11.9255, - 11.9255, - 11.9255, - 11.9255, - 11.9255, - 11.9255, - 11.9255, - 11.9255, - 13.6255, - 13.6255, - 13.6255, - 13.6255, - 13.6255, - 13.6255, - 13.6255, - 13.6255, - 13.6255, - 13.6255, - 15.3255, - 15.3255, - 15.3255, - 15.3255, - 15.3255, - 15.3255, - 15.3255, - 15.3255, - 15.3255, - 15.3255, - 17.0255, - 17.0255, - 17.0255, - 17.0255, - 17.0255 + 9.885499999999999, + 9.885499999999999, + 9.885499999999999, + 9.885499999999999, + 9.885499999999999, + 9.885499999999999, + 9.885499999999999, + 9.885499999999999, + 9.885499999999999, + 9.885499999999999, + 11.5855, + 11.5855, + 11.5855, + 11.5855, + 11.5855, + 11.5855, + 11.5855, + 11.5855, + 11.5855, + 11.5855, + 13.285499999999999, + 13.285499999999999, + 13.285499999999999, + 13.285499999999999, + 13.285499999999999, + 13.285499999999999, + 13.285499999999999, + 13.285499999999999, + 13.285499999999999, + 13.285499999999999, + 14.985499999999998, + 14.985499999999998, + 14.985499999999998, + 14.985499999999998, + 14.985499999999998, + 14.985499999999998, + 14.985499999999998, + 14.985499999999998, + 14.985499999999998, + 14.985499999999998, + 16.685499999999998, + 16.685499999999998, + 16.685499999999998, + 16.685499999999998, + 16.685499999999998, + 16.685499999999998, + 16.685499999999998, + 16.685499999999998, + 16.685499999999998, + 16.685499999999998, + 18.3855, + 18.3855, + 18.3855, + 18.3855, + 18.3855, + 18.3855, + 18.3855, + 18.3855, + 18.3855, + 18.3855, + 20.0855, + 20.0855, + 20.0855, + 20.0855, + 20.0855 ], "y": [ 3.4, @@ -388,7 +388,7 @@ }, "type": "scatter", "x": [ - 11.9255 + 14.985499999999998 ], "y": [ 1 @@ -1222,7 +1222,7 @@ "title": { "text": "Undergraduate Enrollment at Participating Schools" }, - "width": 643.286, + "width": 732.0259999999998, "xaxis": { "showgrid": false, "tickangle": -45, @@ -1234,9 +1234,9 @@ ], "tickvals": [ 1.7, - 3.4084999999999996, - 5.116999999999999, - 11.9255 + 4.4285, + 7.157, + 14.985499999999998 ] }, "yaxis": { @@ -1252,47 +1252,66 @@ "source": [ "import plotly.graph_objects as go\n", "import pandas as pd\n", + "import math\n", "\n", - "def pictogram_bar(df, title, icon_size, max_height=10, units_per_icon=1, column_spacing=0.005,icon_spacing=0.005, scale_factor=1.45,description_of_unit = \"\"):\n", - " \n", + "def pictogram_bar(df,\n", + " x, # string containing the column name of the categories\n", + " y, # string containing the column name of the values\n", + " title=\"\", # title of the figure\n", + " icon_size=25, # icon size in px\n", + " max_icons_per_column=10, \n", + " units_per_icon=1, \n", + " column_spacing=0.005,\n", + " spacing_between_categories=1, # horizontal blank space between categories\n", + " icon_spacing=0.005,\n", + " scale_factor=1.45, #higher values of this move icons farther apart and make the graph bigger\n", + " description_of_unit=\"\" # text for the legend, which contains\n", + " # \"(1 icon =
{units_per_icon} {description_of_unit})\"\n", + "):\n", " fig = go.Figure()\n", - " x_start = 1\n", + " x_coordinate_of_left_edge_of_group = 1\n", " tick_locations = []\n", "\n", - " for i, (category, value) in df.iterrows():\n", - " icon_count = round(value / units_per_icon)\n", - " num_columns = -(-icon_count // max_height) # Ceiling division\n", + " # iterate through each category with its name in the x column and its value in the y column\n", + " # in the data and generate lists of X coordinates and Y coordinates to visualize its value\n", + " # in the form of icons in a single, vertical bar if its value is less than units_per_icon * max_icons_per_column\n", + " # and in the form of multiple columns of icons if its value is greater than that\n", + " for i, row in df.iterrows():\n", + " category=row[x]\n", + " value = row[y]\n", + " icon_count = round(value / units_per_icon) # compute the number of icons needed to represent value\n", + " num_columns = math.ceil(icon_count / max_icons_per_column) # compute the number of columns we'll arrange them into\n", "\n", - " \n", - " \n", - " x_coordinates, y_coordinates = [], []\n", + " #generate list of x and y coordinates for the icons representing this category\n", + " x_coordinates = []\n", + " y_coordinates = []\n", " for col in range(num_columns):\n", - " column_icons = min(max_height, icon_count - col * max_height)\n", - " x_coordinates.extend([(x_start + col)*(1 + icon_spacing)] * column_icons)\n", - " # y_coordinates.extend(range(1, column_icons + 1))\n", + " column_icons = min(max_icons_per_column, icon_count - col * max_icons_per_column)\n", + " x_coordinates.extend([(x_coordinate_of_left_edge_of_group + col)*(1 + icon_spacing)] * column_icons)\n", " y_coordinates.extend([(1 + icon_spacing) * y for y in range(2, column_icons + 2)])\n", "\n", "\n", - " # Add scatter plot for the category\n", + " # Add scatter plot trace for the current category\n", " fig.add_trace(go.Scatter(\n", " x=x_coordinates,\n", " y=y_coordinates,\n", " mode='markers',\n", " marker=dict(size=icon_size, symbol=\"square\", color= i),\n", " hoverinfo=\"text\",\n", + " #make one label for each icon in this category\n", " text=[f\"{category}: {value}\" for _ in range(len(x_coordinates))],\n", " name= f\"(1 icon =
{units_per_icon} {description_of_unit})\",\n", " showlegend=(i==0)\n", "\n", " ))\n", - " \n", - "\n", - " center_of_category_x = (x_start + (num_columns - 1) / 2)*(1 + icon_spacing)\n", "\n", - " # Add value annotations above the section: new line of code \n", + " # compute the x coordinate where we'll label this category\n", + " center_of_category_x = (x_coordinate_of_left_edge_of_group + (num_columns - 1) / 2)*(1 + icon_spacing)\n", + " \n", + " # Add the numeric values for each category underneath the category's icons\n", " fig.add_trace(go.Scatter(\n", " x=[center_of_category_x],\n", - " y=[1],#(max_height+ 1)*(1 + icon_spacing) \n", + " y=[1],#(max_icons_per_column+ 1)*(1 + icon_spacing) \n", " mode=\"text\",\n", " text=[f\"{value:,.0f}\"],\n", " textfont=dict(size=14, color=\"black\"),\n", @@ -1301,32 +1320,36 @@ "\n", " # Track tick locations\n", " tick_locations.append(center_of_category_x)\n", - " x_start += num_columns + column_spacing\n", + " x_coordinate_of_left_edge_of_group += num_columns + column_spacing + spacing_between_categories\n", "\n", - " print(x_start)\n", + " print(x_coordinate_of_left_edge_of_group)\n", " # Update layout\n", " fig.update_layout(\n", " title=title,\n", " xaxis=dict(\n", - " #range=[0,x_start],\n", " tickvals=tick_locations,\n", - " ticktext=list(df[df.columns[0]]),\n", + " ticktext=list(df[x]),\n", " tickangle=-45,\n", " showgrid=False,\n", " ),\n", + " # hide the y-axis\n", " yaxis=dict(\n", " visible= False,\n", - " #scaleanchor = \"x\",\n", - " #scaleratio = 1,\n", " ),\n", " \n", - " legend=dict( #this works best with the big category last, so there will be typically space for a legend in the lower right\n", + " # put the legend in the lower right because \n", + " # this works best with the biggest category last, \n", + " # so there will be typically space in the lower right\n", + " legend=dict( \n", " yanchor=\"top\",\n", " y=-0.1,\n", " xanchor=\"right\",\n", " x=1),\n", - " height=(max_height * (icon_size*(1+icon_spacing)*scale_factor) + 200), #we care about the ratio of the icon size measured in PX to the size of the plot area, so \n", - " width=(x_start * (icon_size*(1+icon_spacing)*scale_factor) + 100) # Done adjusted width based on number of categories\n", + " # we care about the ratio of the icon size measured in PX to the size of the plot area, so \n", + " # we lock the plot area for best results\n", + " height=(max_icons_per_column * (icon_size*(1+icon_spacing)*scale_factor) + 200), \n", + " width=((x_coordinate_of_left_edge_of_group-spacing_between_categories) #subtract to remove spacing between categories to the right of the final category\n", + " * (icon_size*(1+icon_spacing)*scale_factor) + 100) \n", " )\n", "\n", " fig.show()\n", @@ -1339,11 +1362,14 @@ "\n", "pictogram_bar(\n", " df,\n", + " x='School',\n", + " y='Enrollment',\n", " title=\"Undergraduate Enrollment at Participating Schools\",\n", " units_per_icon=1000,\n", " icon_size=20,\n", - " icon_spacing=0.7,\n", - " description_of_unit=\"students\"\n", + " icon_spacing=0.7,\n", + " spacing_between_categories = 0.6,\n", + " description_of_unit=\"students\"\n", ")\n", "\n", "\n" @@ -1355,59 +1381,11 @@ "source": [ "\n" ] - }, - { - "cell_type": "code", - "execution_count": 51, - "metadata": {}, - "outputs": [ - { - "ename": "NameError", - "evalue": "name 'x_start' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[51], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(x_start)\n", - "\u001b[1;31mNameError\u001b[0m: name 'x_start' is not defined" - ] - } - ], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 66, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0 Haverford College\n", - "1 University of Mary Washington\n", - "2 Brown University\n", - "3 Arizona State University\n", - "Name: School, dtype: object" - ] - }, - "execution_count": 66, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { "kernelspec": { - "display_name": "anaconda_312", + "display_name": "justplotly", "language": "python", "name": "python3" }, @@ -1421,7 +1399,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.12.4" + "version": "3.12.7" } }, "nbformat": 4, From b5f18a413e6f8f7565d920ddbb7cdbb6bf12f889 Mon Sep 17 00:00:00 2001 From: Rob Letzler Date: Sat, 25 Jan 2025 23:49:30 -0500 Subject: [PATCH 7/7] Delete scratchwork: doc/python/plotly-universities-1.ipynb --- doc/python/plotly-universities-1.ipynb | 1407 ------------------------ 1 file changed, 1407 deletions(-) delete mode 100644 doc/python/plotly-universities-1.ipynb diff --git a/doc/python/plotly-universities-1.ipynb b/doc/python/plotly-universities-1.ipynb deleted file mode 100644 index 345c7a1ce8..0000000000 --- a/doc/python/plotly-universities-1.ipynb +++ /dev/null @@ -1,1407 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "13.419999999999998\n" - ] - }, - { - "data": { - "application/vnd.plotly.v1+json": { - "config": { - "plotlyServerURL": "https://plot.ly" - }, - "data": [ - { - "hoverinfo": "text", - "marker": { - "color": 0, - "size": 20, - "symbol": "square" - }, - "mode": "markers", - "name": "(1 icon =
1000 students)", - "showlegend": true, - "text": [ - "Haverford College: 1421" - ], - "type": "scatter", - "x": [ - 1.7 - ], - "y": [ - 3.4 - ] - }, - { - "mode": "text", - "showlegend": false, - "text": [ - "1,421" - ], - "textfont": { - "color": "black", - "size": 14 - }, - "type": "scatter", - "x": [ - 1.7 - ], - "y": [ - 1 - ] - }, - { - "hoverinfo": "text", - "marker": { - "color": 1, - "size": 20, - "symbol": "square" - }, - "mode": "markers", - "name": "(1 icon =
1000 students)", - "showlegend": false, - "text": [ - "University of Mary Washington: 3611", - "University of Mary Washington: 3611", - "University of Mary Washington: 3611", - "University of Mary Washington: 3611" - ], - "type": "scatter", - "x": [ - 4.4285, - 4.4285, - 4.4285, - 4.4285 - ], - "y": [ - 3.4, - 5.1, - 6.8, - 8.5 - ] - }, - { - "mode": "text", - "showlegend": false, - "text": [ - "3,611" - ], - "textfont": { - "color": "black", - "size": 14 - }, - "type": "scatter", - "x": [ - 4.4285 - ], - "y": [ - 1 - ] - }, - { - "hoverinfo": "text", - "marker": { - "color": 2, - "size": 20, - "symbol": "square" - }, - "mode": "markers", - "name": "(1 icon =
1000 students)", - "showlegend": false, - "text": [ - "Brown University: 7226", - "Brown University: 7226", - "Brown University: 7226", - "Brown University: 7226", - "Brown University: 7226", - "Brown University: 7226", - "Brown University: 7226" - ], - "type": "scatter", - "x": [ - 7.157, - 7.157, - 7.157, - 7.157, - 7.157, - 7.157, - 7.157 - ], - "y": [ - 3.4, - 5.1, - 6.8, - 8.5, - 10.2, - 11.9, - 13.6 - ] - }, - { - "mode": "text", - "showlegend": false, - "text": [ - "7,226" - ], - "textfont": { - "color": "black", - "size": 14 - }, - "type": "scatter", - "x": [ - 7.157 - ], - "y": [ - 1 - ] - }, - { - "hoverinfo": "text", - "marker": { - "color": 3, - "size": 20, - "symbol": "square" - }, - "mode": "markers", - "name": "(1 icon =
1000 students)", - "showlegend": false, - "text": [ - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174", - "Arizona State University: 65174" - ], - "type": "scatter", - "x": [ - 9.885499999999999, - 9.885499999999999, - 9.885499999999999, - 9.885499999999999, - 9.885499999999999, - 9.885499999999999, - 9.885499999999999, - 9.885499999999999, - 9.885499999999999, - 9.885499999999999, - 11.5855, - 11.5855, - 11.5855, - 11.5855, - 11.5855, - 11.5855, - 11.5855, - 11.5855, - 11.5855, - 11.5855, - 13.285499999999999, - 13.285499999999999, - 13.285499999999999, - 13.285499999999999, - 13.285499999999999, - 13.285499999999999, - 13.285499999999999, - 13.285499999999999, - 13.285499999999999, - 13.285499999999999, - 14.985499999999998, - 14.985499999999998, - 14.985499999999998, - 14.985499999999998, - 14.985499999999998, - 14.985499999999998, - 14.985499999999998, - 14.985499999999998, - 14.985499999999998, - 14.985499999999998, - 16.685499999999998, - 16.685499999999998, - 16.685499999999998, - 16.685499999999998, - 16.685499999999998, - 16.685499999999998, - 16.685499999999998, - 16.685499999999998, - 16.685499999999998, - 16.685499999999998, - 18.3855, - 18.3855, - 18.3855, - 18.3855, - 18.3855, - 18.3855, - 18.3855, - 18.3855, - 18.3855, - 18.3855, - 20.0855, - 20.0855, - 20.0855, - 20.0855, - 20.0855 - ], - "y": [ - 3.4, - 5.1, - 6.8, - 8.5, - 10.2, - 11.9, - 13.6, - 15.299999999999999, - 17, - 18.7, - 3.4, - 5.1, - 6.8, - 8.5, - 10.2, - 11.9, - 13.6, - 15.299999999999999, - 17, - 18.7, - 3.4, - 5.1, - 6.8, - 8.5, - 10.2, - 11.9, - 13.6, - 15.299999999999999, - 17, - 18.7, - 3.4, - 5.1, - 6.8, - 8.5, - 10.2, - 11.9, - 13.6, - 15.299999999999999, - 17, - 18.7, - 3.4, - 5.1, - 6.8, - 8.5, - 10.2, - 11.9, - 13.6, - 15.299999999999999, - 17, - 18.7, - 3.4, - 5.1, - 6.8, - 8.5, - 10.2, - 11.9, - 13.6, - 15.299999999999999, - 17, - 18.7, - 3.4, - 5.1, - 6.8, - 8.5, - 10.2 - ] - }, - { - "mode": "text", - "showlegend": false, - "text": [ - "65,174" - ], - "textfont": { - "color": "black", - "size": 14 - }, - "type": "scatter", - "x": [ - 14.985499999999998 - ], - "y": [ - 1 - ] - } - ], - "layout": { - "height": 693, - "legend": { - "x": 1, - "xanchor": "right", - "y": -0.1, - "yanchor": "top" - }, - "template": { - "data": { - "bar": [ - { - "error_x": { - "color": "#2a3f5f" - }, - "error_y": { - "color": "#2a3f5f" - }, - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "bar" - } - ], - "barpolar": [ - { - "marker": { - "line": { - "color": "#E5ECF6", - "width": 0.5 - }, - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "barpolar" - } - ], - "carpet": [ - { - "aaxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "baxis": { - "endlinecolor": "#2a3f5f", - "gridcolor": "white", - "linecolor": "white", - "minorgridcolor": "white", - "startlinecolor": "#2a3f5f" - }, - "type": "carpet" - } - ], - "choropleth": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "choropleth" - } - ], - "contour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "contour" - } - ], - "contourcarpet": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "contourcarpet" - } - ], - "heatmap": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmap" - } - ], - "heatmapgl": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "heatmapgl" - } - ], - "histogram": [ - { - "marker": { - "pattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - } - }, - "type": "histogram" - } - ], - "histogram2d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2d" - } - ], - "histogram2dcontour": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "histogram2dcontour" - } - ], - "mesh3d": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "type": "mesh3d" - } - ], - "parcoords": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "parcoords" - } - ], - "pie": [ - { - "automargin": true, - "type": "pie" - } - ], - "scatter": [ - { - "fillpattern": { - "fillmode": "overlay", - "size": 10, - "solidity": 0.2 - }, - "type": "scatter" - } - ], - "scatter3d": [ - { - "line": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatter3d" - } - ], - "scattercarpet": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattercarpet" - } - ], - "scattergeo": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergeo" - } - ], - "scattergl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattergl" - } - ], - "scattermapbox": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scattermapbox" - } - ], - "scatterpolar": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolar" - } - ], - "scatterpolargl": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterpolargl" - } - ], - "scatterternary": [ - { - "marker": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "type": "scatterternary" - } - ], - "surface": [ - { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - }, - "colorscale": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "type": "surface" - } - ], - "table": [ - { - "cells": { - "fill": { - "color": "#EBF0F8" - }, - "line": { - "color": "white" - } - }, - "header": { - "fill": { - "color": "#C8D4E3" - }, - "line": { - "color": "white" - } - }, - "type": "table" - } - ] - }, - "layout": { - "annotationdefaults": { - "arrowcolor": "#2a3f5f", - "arrowhead": 0, - "arrowwidth": 1 - }, - "autotypenumbers": "strict", - "coloraxis": { - "colorbar": { - "outlinewidth": 0, - "ticks": "" - } - }, - "colorscale": { - "diverging": [ - [ - 0, - "#8e0152" - ], - [ - 0.1, - "#c51b7d" - ], - [ - 0.2, - "#de77ae" - ], - [ - 0.3, - "#f1b6da" - ], - [ - 0.4, - "#fde0ef" - ], - [ - 0.5, - "#f7f7f7" - ], - [ - 0.6, - "#e6f5d0" - ], - [ - 0.7, - "#b8e186" - ], - [ - 0.8, - "#7fbc41" - ], - [ - 0.9, - "#4d9221" - ], - [ - 1, - "#276419" - ] - ], - "sequential": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ], - "sequentialminus": [ - [ - 0, - "#0d0887" - ], - [ - 0.1111111111111111, - "#46039f" - ], - [ - 0.2222222222222222, - "#7201a8" - ], - [ - 0.3333333333333333, - "#9c179e" - ], - [ - 0.4444444444444444, - "#bd3786" - ], - [ - 0.5555555555555556, - "#d8576b" - ], - [ - 0.6666666666666666, - "#ed7953" - ], - [ - 0.7777777777777778, - "#fb9f3a" - ], - [ - 0.8888888888888888, - "#fdca26" - ], - [ - 1, - "#f0f921" - ] - ] - }, - "colorway": [ - "#636efa", - "#EF553B", - "#00cc96", - "#ab63fa", - "#FFA15A", - "#19d3f3", - "#FF6692", - "#B6E880", - "#FF97FF", - "#FECB52" - ], - "font": { - "color": "#2a3f5f" - }, - "geo": { - "bgcolor": "white", - "lakecolor": "white", - "landcolor": "#E5ECF6", - "showlakes": true, - "showland": true, - "subunitcolor": "white" - }, - "hoverlabel": { - "align": "left" - }, - "hovermode": "closest", - "mapbox": { - "style": "light" - }, - "paper_bgcolor": "white", - "plot_bgcolor": "#E5ECF6", - "polar": { - "angularaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "radialaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "scene": { - "xaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "yaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - }, - "zaxis": { - "backgroundcolor": "#E5ECF6", - "gridcolor": "white", - "gridwidth": 2, - "linecolor": "white", - "showbackground": true, - "ticks": "", - "zerolinecolor": "white" - } - }, - "shapedefaults": { - "line": { - "color": "#2a3f5f" - } - }, - "ternary": { - "aaxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "baxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - }, - "bgcolor": "#E5ECF6", - "caxis": { - "gridcolor": "white", - "linecolor": "white", - "ticks": "" - } - }, - "title": { - "x": 0.05 - }, - "xaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - }, - "yaxis": { - "automargin": true, - "gridcolor": "white", - "linecolor": "white", - "ticks": "", - "title": { - "standoff": 15 - }, - "zerolinecolor": "white", - "zerolinewidth": 2 - } - } - }, - "title": { - "text": "Undergraduate Enrollment at Participating Schools" - }, - "width": 732.0259999999998, - "xaxis": { - "showgrid": false, - "tickangle": -45, - "ticktext": [ - "Haverford College", - "University of Mary Washington", - "Brown University", - "Arizona State University" - ], - "tickvals": [ - 1.7, - 4.4285, - 7.157, - 14.985499999999998 - ] - }, - "yaxis": { - "visible": false - } - } - } - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import plotly.graph_objects as go\n", - "import pandas as pd\n", - "import math\n", - "\n", - "def pictogram_bar(df,\n", - " x, # string containing the column name of the categories\n", - " y, # string containing the column name of the values\n", - " title=\"\", # title of the figure\n", - " icon_size=25, # icon size in px\n", - " max_icons_per_column=10, \n", - " units_per_icon=1, \n", - " column_spacing=0.005,\n", - " spacing_between_categories=1, # horizontal blank space between categories\n", - " icon_spacing=0.005,\n", - " scale_factor=1.45, #higher values of this move icons farther apart and make the graph bigger\n", - " description_of_unit=\"\" # text for the legend, which contains\n", - " # \"(1 icon =
{units_per_icon} {description_of_unit})\"\n", - "):\n", - " fig = go.Figure()\n", - " x_coordinate_of_left_edge_of_group = 1\n", - " tick_locations = []\n", - "\n", - " # iterate through each category with its name in the x column and its value in the y column\n", - " # in the data and generate lists of X coordinates and Y coordinates to visualize its value\n", - " # in the form of icons in a single, vertical bar if its value is less than units_per_icon * max_icons_per_column\n", - " # and in the form of multiple columns of icons if its value is greater than that\n", - " for i, row in df.iterrows():\n", - " category=row[x]\n", - " value = row[y]\n", - " icon_count = round(value / units_per_icon) # compute the number of icons needed to represent value\n", - " num_columns = math.ceil(icon_count / max_icons_per_column) # compute the number of columns we'll arrange them into\n", - "\n", - " #generate list of x and y coordinates for the icons representing this category\n", - " x_coordinates = []\n", - " y_coordinates = []\n", - " for col in range(num_columns):\n", - " column_icons = min(max_icons_per_column, icon_count - col * max_icons_per_column)\n", - " x_coordinates.extend([(x_coordinate_of_left_edge_of_group + col)*(1 + icon_spacing)] * column_icons)\n", - " y_coordinates.extend([(1 + icon_spacing) * y for y in range(2, column_icons + 2)])\n", - "\n", - "\n", - " # Add scatter plot trace for the current category\n", - " fig.add_trace(go.Scatter(\n", - " x=x_coordinates,\n", - " y=y_coordinates,\n", - " mode='markers',\n", - " marker=dict(size=icon_size, symbol=\"square\", color= i),\n", - " hoverinfo=\"text\",\n", - " #make one label for each icon in this category\n", - " text=[f\"{category}: {value}\" for _ in range(len(x_coordinates))],\n", - " name= f\"(1 icon =
{units_per_icon} {description_of_unit})\",\n", - " showlegend=(i==0)\n", - "\n", - " ))\n", - "\n", - " # compute the x coordinate where we'll label this category\n", - " center_of_category_x = (x_coordinate_of_left_edge_of_group + (num_columns - 1) / 2)*(1 + icon_spacing)\n", - " \n", - " # Add the numeric values for each category underneath the category's icons\n", - " fig.add_trace(go.Scatter(\n", - " x=[center_of_category_x],\n", - " y=[1],#(max_icons_per_column+ 1)*(1 + icon_spacing) \n", - " mode=\"text\",\n", - " text=[f\"{value:,.0f}\"],\n", - " textfont=dict(size=14, color=\"black\"),\n", - " showlegend=False,\n", - " ))\n", - "\n", - " # Track tick locations\n", - " tick_locations.append(center_of_category_x)\n", - " x_coordinate_of_left_edge_of_group += num_columns + column_spacing + spacing_between_categories\n", - "\n", - " print(x_coordinate_of_left_edge_of_group)\n", - " # Update layout\n", - " fig.update_layout(\n", - " title=title,\n", - " xaxis=dict(\n", - " tickvals=tick_locations,\n", - " ticktext=list(df[x]),\n", - " tickangle=-45,\n", - " showgrid=False,\n", - " ),\n", - " # hide the y-axis\n", - " yaxis=dict(\n", - " visible= False,\n", - " ),\n", - " \n", - " # put the legend in the lower right because \n", - " # this works best with the biggest category last, \n", - " # so there will be typically space in the lower right\n", - " legend=dict( \n", - " yanchor=\"top\",\n", - " y=-0.1,\n", - " xanchor=\"right\",\n", - " x=1),\n", - " # we care about the ratio of the icon size measured in PX to the size of the plot area, so \n", - " # we lock the plot area for best results\n", - " height=(max_icons_per_column * (icon_size*(1+icon_spacing)*scale_factor) + 200), \n", - " width=((x_coordinate_of_left_edge_of_group-spacing_between_categories) #subtract to remove spacing between categories to the right of the final category\n", - " * (icon_size*(1+icon_spacing)*scale_factor) + 100) \n", - " )\n", - "\n", - " fig.show()\n", - "\n", - "\n", - "df = pd.DataFrame({\n", - " 'School': [\"Haverford College\", \"University of Mary Washington\", \"Brown University\", \"Arizona State University\"],\n", - " 'Enrollment': [1421, 3611, 7226, 65174]\n", - "})\n", - "\n", - "pictogram_bar(\n", - " df,\n", - " x='School',\n", - " y='Enrollment',\n", - " title=\"Undergraduate Enrollment at Participating Schools\",\n", - " units_per_icon=1000,\n", - " icon_size=20,\n", - " icon_spacing=0.7,\n", - " spacing_between_categories = 0.6,\n", - " description_of_unit=\"students\"\n", - ")\n", - "\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "justplotly", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.12.7" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -}