【问题标题】:rotate x-axis text and move y-labels to the top of axes (multiple y-axes)旋转 x 轴文本并将 y 标签移动到轴的顶部(多个 y 轴)
【发布时间】:2018-09-16 23:16:07
【问题描述】:

在下面的 python 代码中,我从数据帧中绘制时间数据和多个 y 值。 现在我想: - 垂直旋转 x 轴的时间值 - 将所有 y 标签 (y1-y4) 移动到轴的顶部 有没有人有建议或解决方案?

import pandas as pd
from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA
import matplotlib.pyplot as plt

data = {'time':['00:00:00','18:00:00','23:59:00'],
          'y1': [1,2,3],'y2': [4,5,6],'y3': [7,8,9],'y4': [10,11,12]}

df=pd.DataFrame(data,columns=['time','y1','y2','y3','y4'])
df['time']=pd.to_datetime(df['time'],format='%H:%M:%S')

host=host_subplot(111,axes_class=AA.Axes)
plt.subplots_adjust(right=0.75)
par1=host.twinx()
par2=host.twinx()
par3=host.twinx()
offset1=40
offset2=80 
new_fixed_axis=par2.get_grid_helper().new_fixed_axis

par2.axis['right']=new_fixed_axis(loc='right',axes=par2,offset=(offset1,0))
par2.axis['right'].toggle(all=True)
par3.axis['right']=new_fixed_axis(loc='right',axes=par3,offset=(offset2,0))
par3.axis['right'].toggle(all=True)

host.set_xlabel('Time')
host.set_ylabel('y1')
par1.set_ylabel('y2')
par2.set_ylabel('y3')
par3.set_ylabel('y4')

p1,=host.plot(df['time'],df['y1'])
p2,=par1.plot(df['time'],df['y2'])
p3,=par2.plot(df['time'],df['y3'])
p4,=par3.plot(df['time'],df['y4'])

host.set_ylim(0,5)
par1.set_ylim(0,8)
par2.set_ylim(0,10)
par3.set_ylim(0,15)

host.legend(loc='upper left',bbox_to_anchor=(0,-.15),ncol=4) 
host.axis['left'].label.set_color(p1.get_color())
host.axis["left"].label.set_rotation(90)

par1.axis['right'].label.set_color(p2.get_color())
par1.axis["right"].label.set_rotation(-90)

par2.axis['right'].label.set_color(p3.get_color())
par2.axis["right"].label.set_rotation(-90)

par3.axis['right'].label.set_color(p4.get_color())
par3.axis["right"].label.set_rotation(-90)

plt.draw()
plt.show()

【问题讨论】:

  • 我有same problem。您找到解决此问题的方法了吗?

标签: python matplotlib plot


【解决方案1】:

第一个问题我有一个解决方案,第二个问题我有一个丑陋的 hack。

1) 旋转 x 轴文本

您需要使用 host.axis 属性进行设置,然后将图例和 xlabel 向下移动一点以腾出空间:

host.legend(loc='upper left',bbox_to_anchor=(0,-.3),ncol=4)  # Lower legend a bit
host.axis["bottom"].label.set_pad(50)  # Lower x-label a bit
host.axis["bottom"].major_ticklabels.set(  # This is the actual rotation command
    rotation=90, verticalalignment='center', horizontalalignment='right', pad=-2)

2) 将 y 标签移动到坐标区的顶部

我在这里尝试的一切都没有奏效。具体来说,我希望以下工作:

par1.axis["right"].label.set_position((1.0, 1.0))

但是相应的get_position 命令不断返回(1.0, 0.5),其中0.5 是轴的中间。由于某种原因,“设置”命令根本不会坚持。这就是丑陋的 hack 出现的地方 - 在标签下方添加空行。所以在你设置标签文本的地方,改成:

new_line_pos_fix = ''.join(['\n'] * 9)  # 9 is the number of blank lines; change as needed
host.set_ylabel('y1' + new_line_pos_fix)
par1.set_ylabel('y2' + new_line_pos_fix)
par2.set_ylabel('y3' + new_line_pos_fix)
par3.set_ylabel('y4' + new_line_pos_fix)

现在我们只需要设置标签的垂直对齐方式,让空白行生效,添加一些填充以提高可读性:

host.axis['right'].label.set(verticalalignment='bottom', pad=7)
par1.axis['right'].label.set(verticalalignment='bottom', pad=7)
par2.axis['right'].label.set(verticalalignment='bottom', pad=7)
par3.axis['right'].label.set(verticalalignment='bottom', pad=7)

如果您想要更有条理的代码,上述命令可以与颜色和旋转设置结合使用,例如:

par1.axis['right'].label.set(color=p2.get_color(), rotation=-90, verticalalignment='bottom', pad=7)

结果:

【讨论】:

  • 亲爱的 Shovalt,很抱歉我的回复晚了(!):
  • 没问题,希望对您有所帮助。
  • 我想写:
    亲爱的 Shovalt,很抱歉我的回复晚了(!):
    非常感谢您的解决方案,两者都运行良好,您太棒了! !
    我只有 1 条评论:
    2) 将 y 标签移动到轴的顶部:
    我已更改:
    host.axis['right '].label.set(verticalalignment='bottom', pad=7)

    to

    host.axis['left'].label.set(verticalalignment='bottom', pad =7)
猜你喜欢
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多