本问题已经有最佳答案,请猛点这里访问。
我正在尝试制作一个负值的条形图,其中基线x轴位于-10而不是0,并且这些值都为-10,因此它们从基线向上延伸。
如果按原样绘制,则条形图向下延伸:
1
2
3import matplotlib.pyplot as plt
vals = [-4, -6, -8, -6, -5]
plt.bar(range(len(vals)), vals)
从某种意义上讲,我可以通过在数据上添加10来伪造它,但是随后我必须删除y-tick值,并且需要保留它们。
1
2
3new_vals = [val + 10 for val in vals]
plt.yticks([])
plt.bar(range(len(new_vals)), new_vals)
那么,如何在第一个图像的y轴上创建第二个图像,并且最好不"伪造"任何数据呢?
stackoverflow.com/a/11250884/8033585显示了如何实现此目的。 与其添加10,不如考虑更改数据符号。 获取标签,然后更改其标志。
每个链接使用fig, ax = plt.subplots()和ax.set_yticklabels(range(-10, 0))为我解决了它,尽管我仍然必须伪造数据。 另外,如果我只是翻转符号,它将改变图形的形状,这不是我想要的。
这不是"伪造数据":您实际上只想绘制data - (-10),即data + 10。 那就是改变基线的工作方式。
尝试matplotlib.axes.Axes.invert_yaxis
1
2
3from matplotlib import pyplot as plt
vals = [-4, -6, -8, -6, -5]
plt.bar(range(len(vals)), vals)
1
2
3fig, ax1 = plt.subplots(1,1)
ax1.bar(range(len(vals)), vals)
ax1.invert_yaxis()
这改变了数据的形状,这不是我要寻找的。 否则,这是一个很好的解决方案。
按照https://matplotlib.org/gallery/ticks_and_spines/custom_ticker1.html示例,您也可以这样做:
1
2
3
4
5
6
7
8
9
10
11from matplotlib.ticker import FuncFormatter
def neg_tick(x, pos):
return '%.1f' % (-x if x else 0) # avoid negative zero (-0.0) labels
formatter = FuncFormatter(neg_tick)
fig, ax = plt.subplots()
ax.yaxis.set_major_formatter(formatter)
plt.bar(range(len(vals)), [-v for v in vals]) # or -numpy.asarray(vals)
# or, let Python enumerate bars:
# plt.bar(*zip(*enumerate(-v for v in vals)))
plt.show()
您不能"伪造"数据。 条形图将向上的条形图表示正面数据,向下绘制的条形图表示负面数据。 如果您希望有所不同,则需要以某种方式欺骗条形图。
IMO,上述解决方案比https://stackoverflow.com/a/11250884/8033585更好,因为它不需要画画布,更改标签等技巧。
如果您确实希望"恢复"钢筋长度(如您的示例中所示),则可以执行以下操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15from matplotlib.ticker import FuncFormatter
import numpy as np
# shifted up:
vals = np.asarray(vals)
minval = np.amin(vals)
minval += np.sign(minval) #"add" 1 so that"lowest" bar is still drawn
def neg_tick(x, pos):
return '%.1f' % (x + minval if x != minval else 0)
formatter = FuncFormatter(neg_tick)
fig, ax = plt.subplots()
ax.yaxis.set_major_formatter(formatter)
plt.bar(*zip(*enumerate(-minval + vals)))
plt.show()