我已经检查了以下相关问题:
...不幸的是,我无法真正使用它们来找到解决问题的方法:
因此,我有两个函数,我想在每个子图中绘制它们-但是,它们应该有一个共享的x轴。但是,我也想要一个双x轴-在一种情况下,x轴代表百分比(从0到100);在另一种情况下,x轴表示相同的值,表示为16位整数(相应的范围是从0到65535)。最后,我要在子图中绘制箭头。
通读SO上的示例,我几乎可以做到这一点-除非当我开始使用交互式绘图时,一旦我开始移动或缩放绘图,就可以做到:
有什么方法可以做到这一点?对于下面粘贴的代码(Windows 10上的MSYS2 / MINGW64上的Matplotlib 3.1.1,Python 3.7.4),这是我另外得到的动画gif的结果:
代码是这样的:
#!/usr/bin/env python
import matplotlib
print("matplotlib.__version__ {}".format(matplotlib.__version__))
import matplotlib.pyplot as plt
import numpy as np
# https://stackoverflow.com/questions/33737736/matplotlib-axis-arrow-tip
def arrowed_spines(fig, ax):
xmin, xmax = ax.get_xlim()
ymin, ymax = ax.get_ylim()
## removing the default axis on all sides:
#for side in ['bottom','right','top','left']:
# ax.spines[side].set_visible(False)
#
## removing the axis ticks
#plt.xticks([]) # labels
#plt.yticks([])
#ax.xaxis.set_ticks_position('none') # tick markers
#ax.yaxis.set_ticks_position('none')
# get width and height of axes object to compute
# matching arrowhead length and width
dps = fig.dpi_scale_trans.inverted()
bbox = ax.get_window_extent().transformed(dps)
width, height = bbox.width, bbox.height
# manual arrowhead width and length
hw = 1./20.*(ymax-ymin)
hl = 1./20.*(xmax-xmin)
lw = 1. # axis line width
ohg = 0.3 # arrow overhang
# compute matching arrowhead length and width
yhw = hw/(ymax-ymin)*(xmax-xmin)* height/width
yhl = hl/(xmax-xmin)*(ymax-ymin)* width/height
# draw x and y axis
# for some reason, for a straight line here at ymin, the 4th arg needs to be 0, not y?!
ax.arrow(xmin, ymin, xmax-xmin, 0, fc='k', ec='k', lw = lw,
head_width=hw, head_length=hl, overhang = ohg,
length_includes_head= True, clip_on = False)
ax.arrow(0, ymin, 0., ymax-ymin, fc='k', ec='k', lw = lw,
head_width=yhw, head_length=yhl, overhang = ohg,
length_includes_head= True, clip_on = False)
def main():
xdata = np.arange(0, 101, 1) # 0 to 100, both included
ydata1 = np.sin(0.01*xdata*np.pi/2)
ydata2 = 10*np.sin(0.01*xdata*np.pi/4)
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=(9, 6), dpi=120, gridspec_kw={'height_ratios': [2, 1]})
fig.subplots_adjust(hspace=0)
pl21, = ax1.plot(xdata, ydata1, color="Red")
pl22, = ax2.plot(xdata, ydata2, color="Khaki")
# zeroline
ax1.axhline(y=0, color='gray', linestyle='-', linewidth=0.5)
arrowed_spines(fig, ax1)
arrowed_spines(fig, ax2)
ax2.set_xlim(0, 100)
ax2.set_xlabel('IN [%]', fontsize = 9)
ax2.xaxis.set_label_coords(0.5, -0.1)
# https://stackoverflow.com/questions/31803817/how-to-add-second-x-axis-at-the-bottom-of-the-first-one-in-matplotlib
ax22 = ax2.twiny() # instantiate a second axes that shares the same y-axis
# ax2.get_shared_x_axes().join(ax2, ax22) # this kills the plotting entirely; https://stackoverflow.com/questions/42973223/
ax22.set_xlim(0, 65535)
# Move twinned axis ticks and label from top to bottom
ax22.xaxis.set_ticks_position("bottom")
ax22.xaxis.set_label_position("bottom")
# Offset the twin axis below the host
ax22.spines["bottom"].set_position(("axes", -0.2))
# Turn on the frame for the twin axis, but then hide all
# but the bottom spine
ax22.set_frame_on(True)
ax22.patch.set_visible(False)
ax22.spines["bottom"].set_visible(True)
ax22.set_xlabel('IN [16-bit]', fontsize = 9)
ax22.xaxis.set_label_coords(0.5, -0.34)
plt.show()
# ENTRY POINT
if __name__ == '__main__':
main()