Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitda9d058

Browse files
authored
Merge pull request#28163 from meeseeksmachine/auto-backport-of-pr-28144-on-v3.9.x
Backport PR#28144 on branch v3.9.x (DOC: Refactor code in the fishbone diagram example)
2 parents8b796c4 +7130c9c commitda9d058

File tree

1 file changed

+75
-82
lines changed

1 file changed

+75
-82
lines changed

‎galleries/examples/specialty_plots/ishikawa_diagram.py

Lines changed: 75 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
Source: https://en.wikipedia.org/wiki/Ishikawa_diagram
1010
1111
"""
12+
importmath
13+
1214
importmatplotlib.pyplotasplt
1315

1416
frommatplotlib.patchesimportPolygon,Wedge
1517

16-
# Create the fishbone diagram
1718
fig,ax=plt.subplots(figsize=(10,6),layout='constrained')
1819
ax.set_xlim(-5,5)
1920
ax.set_ylim(-5,5)
@@ -22,18 +23,18 @@
2223

2324
defproblems(data:str,
2425
problem_x:float,problem_y:float,
25-
prob_angle_x:float,prob_angle_y:float):
26+
angle_x:float,angle_y:float):
2627
"""
2728
Draw each problem section of the Ishikawa plot.
2829
2930
Parameters
3031
----------
3132
data : str
32-
Thecategoryname.
33+
The name of the problem category.
3334
problem_x, problem_y : float, optional
3435
The `X` and `Y` positions of the problem arrows (`Y` defaults to zero).
35-
prob_angle_x, prob_angle_y : float, optional
36-
The angle of the problem annotations. They are angled towards
36+
angle_x, angle_y : float, optional
37+
The angle of the problem annotations. They arealwaysangled towards
3738
the tail of the plot.
3839
3940
Returns
@@ -42,8 +43,8 @@ def problems(data: str,
4243
4344
"""
4445
ax.annotate(str.upper(data),xy=(problem_x,problem_y),
45-
xytext=(prob_angle_x,prob_angle_y),
46-
fontsize='10',
46+
xytext=(angle_x,angle_y),
47+
fontsize=10,
4748
color='white',
4849
weight='bold',
4950
xycoords='data',
@@ -56,7 +57,8 @@ def problems(data: str,
5657
pad=0.8))
5758

5859

59-
defcauses(data:list,cause_x:float,cause_y:float,
60+
defcauses(data:list,
61+
cause_x:float,cause_y:float,
6062
cause_xytext=(-9,-0.3),top:bool=True):
6163
"""
6264
Place each cause to a position relative to the problems
@@ -72,34 +74,33 @@ def causes(data: list, cause_x: float, cause_y: float,
7274
cause_xytext : tuple, optional
7375
Adjust to set the distance of the cause text from the problem
7476
arrow in fontsize units.
75-
top : bool
77+
top : bool, default: True
78+
Determines whether the next cause annotation will be
79+
plotted above or below the previous one.
7680
7781
Returns
7882
-------
7983
None.
8084
8185
"""
8286
forindex,causeinenumerate(data):
83-
# First cause annotation is placed in the middle of the problems arrow
87+
# [<x pos>, <y pos>]
88+
coords= [[0.02,0],
89+
[0.23,0.5],
90+
[-0.46,-1],
91+
[0.69,1.5],
92+
[-0.92,-2],
93+
[1.15,2.5]]
94+
95+
# First 'cause' annotation is placed in the middle of the 'problems' arrow
8496
# and each subsequent cause is plotted above or below it in succession.
85-
86-
# [<x pos>, [<y pos top>, <y pos bottom>]]
87-
coords= [[0, [0,0]],
88-
[0.23, [0.5,-0.5]],
89-
[-0.46, [-1,1]],
90-
[0.69, [1.5,-1.5]],
91-
[-0.92, [-2,2]],
92-
[1.15, [2.5,-2.5]]]
93-
iftop:
94-
cause_y+=coords[index][1][0]
95-
else:
96-
cause_y+=coords[index][1][1]
9797
cause_x-=coords[index][0]
98+
cause_y+=coords[index][1]iftopelse-coords[index][1]
9899

99100
ax.annotate(cause,xy=(cause_x,cause_y),
100101
horizontalalignment='center',
101102
xytext=cause_xytext,
102-
fontsize='9',
103+
fontsize=9,
103104
xycoords='data',
104105
textcoords='offset fontsize',
105106
arrowprops=dict(arrowstyle="->",
@@ -108,82 +109,74 @@ def causes(data: list, cause_x: float, cause_y: float,
108109

109110
defdraw_body(data:dict):
110111
"""
111-
Place each section in its correct place by changing
112+
Place eachproblemsection in its correct place by changing
112113
the coordinates on each loop.
113114
114115
Parameters
115116
----------
116117
data : dict
117-
The input data (can belistortuple). ValueError is
118-
raised if more than six arguments are passed.
118+
The input data (can bea dict of listsortuples). ValueError
119+
israised if more than six arguments are passed.
119120
120121
Returns
121122
-------
122123
None.
123124
124125
"""
125-
second_sections= []
126-
third_sections= []
127-
# Resize diagram to automatically scale in response to the number
128-
# of problems in the input data.
129-
iflen(data)==1orlen(data)==2:
130-
spine_length= (-2.1,2)
131-
head_pos= (2,0)
132-
tail_pos= ((-2.8,0.8), (-2.8,-0.8), (-2.0,-0.01))
133-
first_section= [1.6,0.8]
134-
eliflen(data)==3orlen(data)==4:
135-
spine_length= (-3.1,3)
136-
head_pos= (3,0)
137-
tail_pos= ((-3.8,0.8), (-3.8,-0.8), (-3.0,-0.01))
138-
first_section= [2.6,1.8]
139-
second_sections= [-0.4,-1.2]
140-
else:# len(data) == 5 or 6
141-
spine_length= (-4.1,4)
142-
head_pos= (4,0)
143-
tail_pos= ((-4.8,0.8), (-4.8,-0.8), (-4.0,-0.01))
144-
first_section= [3.5,2.7]
145-
second_sections= [1,0.2]
146-
third_sections= [-1.5,-2.3]
147-
148-
# Change the coordinates of the annotations on each loop.
126+
# Set the length of the spine according to the number of 'problem' categories.
127+
length= (math.ceil(len(data)/2))-1
128+
draw_spine(-2-length,2+length)
129+
130+
# Change the coordinates of the 'problem' annotations after each one is rendered.
131+
offset=0
132+
prob_section= [1.55,0.8]
149133
forindex,probleminenumerate(data.values()):
150-
top_row=True
151-
cause_arrow_y=1.7
152-
ifindex%2!=0:# Plot problems below the spine.
153-
top_row=False
154-
y_prob_angle=-16
155-
cause_arrow_y=-1.7
156-
else:# Plot problems above the spine.
157-
y_prob_angle=16
158-
# Plot the 3 sections in pairs along the main spine.
159-
ifindexin (0,1):
160-
prob_arrow_x=first_section[0]
161-
cause_arrow_x=first_section[1]
162-
elifindexin (2,3):
163-
prob_arrow_x=second_sections[0]
164-
cause_arrow_x=second_sections[1]
165-
else:
166-
prob_arrow_x=third_sections[0]
167-
cause_arrow_x=third_sections[1]
134+
plot_above=index%2==0
135+
cause_arrow_y=1.7ifplot_aboveelse-1.7
136+
y_prob_angle=16ifplot_aboveelse-16
137+
138+
# Plot each section in pairs along the main spine.
139+
prob_arrow_x=prob_section[0]+length+offset
140+
cause_arrow_x=prob_section[1]+length+offset
141+
ifnotplot_above:
142+
offset-=2.5
168143
ifindex>5:
169144
raiseValueError(f'Maximum number of problems is 6, you have entered '
170145
f'{len(data)}')
171146

172-
# draw main spine
173-
ax.plot(spine_length, [0,0],color='tab:blue',linewidth=2)
174-
# draw fish head
175-
ax.text(head_pos[0]+0.1,head_pos[1]-0.05,'PROBLEM',fontsize=10,
176-
weight='bold',color='white')
177-
semicircle=Wedge(head_pos,1,270,90,fc='tab:blue')
178-
ax.add_patch(semicircle)
179-
# draw fishtail
180-
triangle=Polygon(tail_pos,fc='tab:blue')
181-
ax.add_patch(triangle)
182-
# Pass each category name to the problems function as a string on each loop.
183147
problems(list(data.keys())[index],prob_arrow_x,0,-12,y_prob_angle)
184-
# Start the cause function with the first annotation being plotted at
185-
# the cause_arrow_x, cause_arrow_y coordinates.
186-
causes(problem,cause_arrow_x,cause_arrow_y,top=top_row)
148+
causes(problem,cause_arrow_x,cause_arrow_y,top=plot_above)
149+
150+
151+
defdraw_spine(xmin:int,xmax:int):
152+
"""
153+
Draw main spine, head and tail.
154+
155+
Parameters
156+
----------
157+
xmin : int
158+
The default position of the head of the spine's
159+
x-coordinate.
160+
xmax : int
161+
The default position of the tail of the spine's
162+
x-coordinate.
163+
164+
Returns
165+
-------
166+
None.
167+
168+
"""
169+
# draw main spine
170+
ax.plot([xmin-0.1,xmax], [0,0],color='tab:blue',linewidth=2)
171+
# draw fish head
172+
ax.text(xmax+0.1,-0.05,'PROBLEM',fontsize=10,
173+
weight='bold',color='white')
174+
semicircle=Wedge((xmax,0),1,270,90,fc='tab:blue')
175+
ax.add_patch(semicircle)
176+
# draw fish tail
177+
tail_pos= [[xmin-0.8,0.8], [xmin-0.8,-0.8], [xmin,-0.01]]
178+
triangle=Polygon(tail_pos,fc='tab:blue')
179+
ax.add_patch(triangle)
187180

188181

189182
# Input data

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp