matplotlib双y轴

时间:2017-11-23 08:02:08

标签: python matplotlib

the chart

径流和值分别有13个数据。双y轴用于每年比较两组数据。但由于每年都有不对齐的红色符号和蓝色符号,这个数字是错误的。我错过了什么细节吗?

runoff=[1877, 2690.9, 3632, 4525, 1512, 4459, 1614.3, 2595, 1270.2, 2308.2, 2436, 1742.8,2658.7]
TSM=['22.805241997828', '26.649050918463', '23.875097901606', '22.60339679601', '25.898807017902', '28.610553136975', '28.489485098388', '22.206851921378', '21.958918945009', '15.629827074318', '18.894425896003', '20.511980938426', '19.879687929129']

def draw(df):

    font = {'family' : 'Times New Roman',             
        'color'  : 'black'          ,  
        'weight' : 'normal'         ,  
        'size'   : 11 
        }

    fig=plt.figure(11,figsize=(4.5,3))
    ax1=plt.axes([0.10,0.24,0.78,0.73])
    ax2=ax1.twinx()
    matplotlib.rcParams["font.family"] = "Times New Roman"#全局times new roamn
    matplotlib.rcParams['xtick.direction'] = 'in'
    matplotlib.rcParams['ytick.direction'] = 'inout' 
    ax1.plot(value,label='TSM',marker='o',color='red')
    #plt.ylim([10,30])


    ax2.plot(runoff,label='Sediment runoff',marker='s',color='blue',linestyle='--')
    ax2.spines['left'].set_color('red')
    ax2.spines['right'].set_color('blue')
    ax2.tick_params(which='both',color='blue')
    ax1.tick_params(axis='y',which='both',color='red')

    xticks=list(range(0,len(time),2))
    xlabels=[time[index] for index in xticks]
    xticks.append(len(time)+1)
    #xlabels.append('2015')
    #xlabels.append('2016')
    ax1.set_xticks(xticks)
    ax1.set_xticklabels(xlabels,rotation=0,fontdict=font)


    ax2.spines['bottom'].set_linewidth(1.25)
    ax2.spines['left'].set_linewidth(1.25) 
    ax2.spines['right'].set_linewidth(1.25) 
    ax2.spines['top'].set_linewidth(1.25) 

    legend1=ax1.legend(loc=1,ncol=2)
    legend1.get_title().set_fontsize(fontsize=20)
    legend2=ax2.legend(loc=0,bbox_to_anchor=(0.6,0.85),borderaxespad=0.)
    legend2.get_title().set_fontsize(fontsize=20)

    f=plt.gcf()
    f.text(0.001,0.7,u'TSM $(mg/L)$',fontdict=font,color='black',rotation=90)
    f.text(0.5,0.09,u'Time (year)',fontdict=font,color='black')
    f.text(0.99,0.82,u'Sediment runoff ($ton$)',fontdict=font,color='black',rotation=90)  
    f.canvas.draw()
    plt.show()
    return True

2 个答案:

答案 0 :(得分:0)

一种直接的方法是首先确保您从数据框中正确地计算您的时间(2003年至2015年),以创建年份列表,在您的代码中称为“时间”。我使用了一个简单的列表(范围(..)使用Python 3.'time'变量作为年份列表将使下一行不必要(“#xticks.append(len(time)+1)”): 另请注意,您的(df)参数不是必需的,因为它不在draw()中使用。 我编写了另一种组合两个轴的图例的方法。我在建议的代码中完成了这个: 1)创建组合轴定义(AxesAll = axes1 + axes2,而不是先前ax1.plot(...)语句中的axes1 = ...,类似于axes2),然后为它们定义组合图例。

import matplotlib.pyplot as plt
import matplotlib

time = list(range(2003,2016))
#print(time)

runoff=[1877, 2690.9, 3632, 4525, 1512, 4459, 1614.3, 2595, 1270.2, 2308.2, 
2436, 1742.8,2658.7]
TSM=['22.805241997828', '26.649050918463', '23.875097901606', '22.60339679601', '25.898807017902', '28.610553136975', '28.489485098388', '22.206851921378', '21.958918945009', '15.629827074318', '18.894425896003', '20.511980938426', '19.879687929129']

def draw():

    font = {'family' : 'Times New Roman',             
    'color'  : 'black'          ,  
    'weight' : 'normal'         ,  
    'size'   : 11 
    }

    fig=plt.figure(11,figsize=(4.5,3))
    ax1=plt.axes([0.10,0.24,0.78,0.73])
    ax2=ax1.twinx()
    matplotlib.rcParams["font.family"] = "Times New Roman"#全局times new roamn
    matplotlib.rcParams['xtick.direction'] = 'in'
    matplotlib.rcParams['ytick.direction'] = 'inout' 
    axes1 = ax1.plot(TSM,label='TSM',marker='o',color='red')
    #plt.ylim([10,30])


    axes2 = ax2.plot(runoff,label='Sediment runoff',marker='s',color='blue',linestyle='--')
    ax2.spines['left'].set_color('red')
    ax2.spines['right'].set_color('blue')
    ax2.tick_params(which='both',color='blue')
    ax1.tick_params(axis='y',which='both',color='red')

    xticks=list(range(0,len(time),2))
    xlabels=[time[index] for index in xticks]
    #xticks.append(len(time)+1)
    #xlabels.append('2015')
    #xlabels.append('2016')
    ax1.set_xticks(xticks)
    ax1.set_xticklabels(xlabels,rotation=0,fontdict=font)


    ax2.spines['bottom'].set_linewidth(1.25)
    ax2.spines['left'].set_linewidth(1.25) 
    ax2.spines['right'].set_linewidth(1.25)
    ax2.spines['top'].set_linewidth(1.25) 

    #legend1=ax1.legend(loc=1,ncol=2)
    #legend1.get_title().set_fontsize(fontsize=20)
    #legend2=ax2.legend(loc=0,bbox_to_anchor=(0.6,0.85),borderaxespad=0.)
    #legend2.get_title().set_fontsize(fontsize=20)
    axesAll = axes1+axes2
    labsAll = (l.get_label() for l in axesAll)
    plt.legend(axesAll, labsAll, loc=0)

    f=plt.gcf()
    f.text(0.001,0.7,u'TSM 
    $(mg/L)$',fontdict=font,color='black',rotation=90)
    f.text(0.5,0.09,u'Time (year)',fontdict=font,color='black')
    f.text(0.99,0.82,u'Sediment runoff ($ton$)',fontdict=font,color='black',rotation=90)  
    f.canvas.draw()
    plt.show()
    return True

draw()

答案 1 :(得分:0)

您有一个简单的问题 - 在twinx上实际设置x轴之前,您正在ax1上调用ax1来创建ax2。在调用ax2 = ax1.twinx()

之前将x轴设置代码移动到之前

移动它:

xticks=list(range(0,len(time),2))
xlabels=[time[index] for index in xticks]
xticks.append(len(time)+1)
#xlabels.append('2015')
#xlabels.append('2016')
ax1.set_xticks(xticks)
ax1.set_xticklabels(xlabels,rotation=0,fontdict=font)

来到这里

ax1=plt.axes([0.10,0.24,0.78,0.73])
#INSERT HERE
...
#END OF INSERT
ax2=ax1.twinx()