@@ -224,52 +224,51 @@ Diverging bar charts offer two imperfect options for responses that are neither
224224import pandas as pd
225225import plotly.graph_objects as go
226226
227- data = {
228- "Category": ["Content Quality", "Value for Money", "Ease of Use", "Customer Support", "Scale Fidelity"],
229- "Neutral": [10, 15, 18, 15,20],
230- "Somewhat Agree": [25, 25, 22, 20, 20],
231- "Strongly Agree": [35, 35, 25, 40, 20],
232- "Somewhat Disagree": [-20, -15, -20, -10, -20],
233- "Strongly Disagree": [-10, -10, -15, -15,-20]
234- }
235- df = pd.DataFrame(data)
227+
228+ df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/refs/heads/master/gss_2002_5_pt_likert.csv')
229+ #data source details are in this CSV file
230+ df.rename(columns={'Unnamed: 0':"Category"}, inplace=True)
231+
232+
233+ #achieve the diverging effect by putting a negative sign on the "disagree" answers
234+ for v in ["Disagree","Strongly Disagree"]:
235+ df[v]=df[v]*-1
236236
237237fig = go.Figure()
238- # this color palette conveys meaning: blues for negative, reds for positive, gray for neutral
238+ # this color palette conveys meaning: blues for negative, reds for positive, gray for Neither Agree nor Disagree
239239color_by_category={
240240 "Strongly Agree":'darkblue',
241- "Somewhat Agree":'lightblue',
242- "Somewhat Disagree":'orange',
241+ "Agree":'lightblue',
242+ "Disagree":'orange',
243243 "Strongly Disagree":'red',
244- "Neutral ":'gray',
244+ "Neither Agree nor Disagree ":'gray',
245245}
246246
247+
247248# We want the legend to be ordered in the same order that the categories appear, left to right --
248249# which is different from the order in which we have to add the traces to the figure.
249250# since we need to create the "somewhat" traces before the "strongly" traces to display
250251# the segments in the desired order
251252
252253legend_rank_by_category={
253254 "Strongly Disagree":1,
254- "Somewhat Disagree":2,
255- "Somewhat Agree":3,
255+ "Disagree":2,
256+ "Agree":3,
256257 "Strongly Agree":4,
257- "Neutral ":5
258+ "Neither Agree nor Disagree ":5
258259}
259260
260261# Add bars
261- for col in df[["Somewhat Disagree","Strongly Disagree","Somewhat Agree","Strongly Agree","Neutral "]]:
262+ for col in df[["Disagree","Strongly Disagree","Agree","Strongly Agree","Neither Agree nor Disagree "]]:
262263 fig.add_trace(go.Bar(
263264 y=df["Category"],
264265 x=df[col],
265266 name=col,
266267 orientation='h',
267268 marker=dict(color=color_by_category[col]),
268269 legendrank=legend_rank_by_category[col],
269- xaxis=f"x{1+(col=="Neutral ")}", # in this context, putting neutral on a secondary x-axis on a different domain
270+ xaxis=f"x{1+(col=="Neither Agree nor Disagree ")}", # in this context, putting "Neither Agree nor Disagree" on a secondary x-axis on a different domain
270271 # yields results equivalent to subplots with far less code
271-
272-
273272 )
274273)
275274
@@ -278,15 +277,16 @@ for col in df[["Somewhat Disagree","Strongly Disagree","Somewhat Agree","Strongl
278277
279278# Find the maximum width of the bars to the left and right sides of the origin; remember that the width of
280279# the plot is the sum of the longest negative bar and the longest positive bar even if they are on separate rows
281- max_left = min(df[["Somewhat Disagree","Strongly Disagree"]].sum(axis=1))
282- max_right = max(df[["Somewhat Agree","Strongly Agree"]].sum(axis=1))
280+ max_left = min(df[["Disagree","Strongly Disagree"]].sum(axis=1))
281+ max_right = max(df[["Agree","Strongly Agree"]].sum(axis=1))
283282
284283# we are working in percent, but coded the negative reactions as negative numbers; so we need to take the absolute value
285284max_width_signed = abs(max_left)+max_right
286- max_width_neutral = max(df["Neutral "])
285+ max_width_neither = max(df["Neither Agree nor Disagree "])
287286
288287fig.update_layout(
289- title="Reactions to the statement, 'The service met your expectations for':",
288+
289+ title="Reactions to statements from the 2002 General Social Survey:",
290290 plot_bgcolor="white",
291291 barmode='relative', # Allows bars to diverge from the center
292292 )
@@ -296,12 +296,12 @@ fig.update_xaxes(
296296 #starting here, we set domain and range to create a shared x-axis scale
297297 # multiply by .98 to add space between the two columns
298298 range=[max_left, max_right],
299- domain=[0, 0.98*(max_width_signed/(max_width_signed+max_width_neutral ))]
299+ domain=[0, 0.98*(max_width_signed/(max_width_signed+max_width_neither ))]
300300)
301301fig.update_layout(
302302 xaxis2=dict(
303- range=[0, max_width_neutral ],
304- domain=[(1-.98*(1-max_width_signed/(max_width_signed+max_width_neutral ))), 1.0],
303+ range=[0, max_width_neither ],
304+ domain=[(1-.98*(1-max_width_signed/(max_width_signed+max_width_neither ))), 1.0],
305305 )
306306)
307307fig.update_legends(
0 commit comments