Skip to content

Commit 4891d9e

Browse files
authored
Merge pull request #31 from RemDelaporteMathurin/horizontal_bar_chart
Support for horizontal barchart
2 parents 68c0fc4 + 5ffbfbc commit 4891d9e

2 files changed

Lines changed: 59 additions & 11 deletions

File tree

src/matplotx/_labels.py

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -162,30 +162,58 @@ def ylabel_top(string: str) -> None:
162162
yl.set_rotation(0)
163163

164164

165-
def show_bar_values(fmt: str = "{}") -> None:
165+
def show_bar_values(fmt: str = "{}", alignment: str = "vertical") -> None:
166166
ax = plt.gca()
167167

168-
# turn off y-ticks and y-grid
169-
plt.tick_params(axis="y", which="both", left=False, right=False, labelleft=False)
168+
# check alignment
169+
if alignment not in ["vertical", "horizontal"]:
170+
msg = "Unknown alignment {}".format(alignment)
171+
msg += " (should be horizontal or vertical)"
172+
raise ValueError(msg)
173+
174+
# turn off ticks and grid
175+
if alignment == "vertical":
176+
plt.tick_params(
177+
axis="y", which="both", left=False, right=False, labelleft=False
178+
)
179+
elif alignment == "horizontal":
180+
plt.tick_params(
181+
axis="x", which="both", bottom=False, top=False, labelbottom=False
182+
)
183+
170184
plt.grid(False)
171185

172186
# remove margins
173-
plt.margins(x=0)
187+
plt.margins(x=0, y=0)
174188

175189
data_to_axis = ax.transData + ax.transAxes.inverted()
176190
axis_to_data = ax.transAxes + ax.transData.inverted()
177191

178192
for rect in ax.patches:
179-
height = rect.get_height()
180-
ypos_ax = data_to_axis.transform([1.0, height])
181-
ypos = axis_to_data.transform(ypos_ax - 0.1)[1]
193+
if alignment == "vertical":
194+
height = rect.get_height()
195+
ypos_ax = data_to_axis.transform([1.0, height])
196+
ypos = axis_to_data.transform(ypos_ax - 0.1)[1]
197+
xpos = rect.get_x() + rect.get_width() / 2
198+
s = fmt.format(height)
199+
ha = "center"
200+
va = "bottom"
201+
elif alignment == "horizontal":
202+
width = rect.get_width()
203+
xpos_ax = data_to_axis.transform([1.0, width])
204+
xpos = axis_to_data.transform(xpos_ax - 0.1)[1]
205+
ypos = rect.get_y() + rect.get_height() / 2
206+
s = fmt.format(width)
207+
ha = "right"
208+
va = "center"
209+
182210
ax.text(
183-
rect.get_x() + rect.get_width() / 2,
211+
xpos,
184212
ypos,
185-
fmt.format(height),
213+
s,
186214
size=14,
187215
weight="bold",
188-
ha="center",
189-
va="bottom",
216+
ha=ha,
217+
va=va,
190218
color="white",
191219
)

tests/test_bar.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import matplotlib.pyplot as plt
2+
import pytest
23

34
import matplotx
45

@@ -15,6 +16,25 @@ def test_bar():
1516
plt.close()
1617

1718

19+
def test_bar_horizontal():
20+
"""Checks that a bar chart can be created with horizontal alignment"""
21+
with plt.style.context(matplotx.styles.dufte_bar):
22+
labels = ["label 1", "label 2"]
23+
vals = [2.1, 6.3]
24+
ypos = range(len(vals))
25+
plt.barh(ypos, vals)
26+
plt.xticks(ypos, labels)
27+
matplotx.show_bar_values("{:.2f}", alignment="horizontal")
28+
plt.title("some title")
29+
plt.close()
30+
31+
32+
def test_wrong_alignment():
33+
"""Checks that an error is raised when alignment has an invalid value"""
34+
with pytest.raises(ValueError, match="Unknown alignment"):
35+
matplotx.show_bar_values(alignment="coucou")
36+
37+
1838
if __name__ == "__main__":
1939
test_bar()
2040
plt.show()

0 commit comments

Comments
 (0)