Search code examples
pythondatetimematplotlibplotaxis-labels

Write two or three x ticks labels, showing the Hour in UT and MLT (magnetic local time) using matplotlib


I'm trying to make this plot, similar to the example figure attached. I also attached the example data.

Example data

I want to plot one column (BLC 73.61, FCC 68.5, BSL 40.69) versus time, that are in the index of the data frame, and together with the datetime xticks and want to show the correspondent MLT (Magnetic local time) value, that are in the fourth column of the database.

Here is an code that I'm trying to do:

The picture show an example of I want to do. The x ticks labels showing in one line the value of uT hour in datetime format and in a second or third line show the correspondent value of the MLT

# read the data
data = pd.read_csv('dados.csv', index_col=[0])

#plotting 
fig = plt.figure(figsize=(10, 5)) #
ax1 = fig.add_subplot(111)
ax2 = ax1.twiny() # second x-axis
ax1.plot(data.index,data['BLC 73.61'])
ax2.xaxis.set_ticks_position("bottom")
ax2.xaxis.set_label_position("bottom")
ax2.spines["bottom"].set_position(("axes", -0.2))
ax2.spines['bottom'].set_color('none')

majorLocator   = MultipleLocator(1)
minorLocator   = MultipleLocator(1)
ax1.xaxis.set_major_locator(majorLocator)
ax1.xaxis.set_minor_locator(minorLocator)
ax1.xaxis.set_major_locator(majorLocator)
ax1.xaxis.set_minor_locator(minorLocator)
ax1.xaxis.set_minor_formatter(dates.DateFormatter('%H:%M'))
ax1.xaxis.set_minor_locator(mdates.MinuteLocator(interval=30))
ax1.xaxis.set_major_formatter(dates.DateFormatter('%H:%M\n%b %d, %Y'))
ax1.xaxis.set_major_locator(mdates.HourLocator(interval=30))

ax2.set_xticklabels(data['MLT'].values)

# ax2.xaxis.set_minor_formatter(dates.DateFormatter('%H:%M'))
# ax2.xaxis.set_minor_locator(mdates.MinuteLocator(interval=30))
# ax2.xaxis.set_major_formatter(dates.DateFormatter('%H:%M\n%b %d, %Y'))
# ax2.xaxis.set_major_locator(mdates.HourLocator(interval=30))
a=ax2.get_xticks().tolist()

And here is what i'm getting as result:

Result


Solution

  • I just found one solution for this.

    I've created a function defining how I wanted the ticks and used the FuncFormatter module.

    def format_func(value, tick_number):
    
        hora = mdates.num2date(value)
        teste = mlt['BLC 73.61'][hora]
        return ('%d:%d \n %0.1f'  % (hora.hour, hora.minute,teste))
    
    def format_func2(value, tick_number):
        # find the first value
        if tick_number == 0:
            return ('hh:mm     \n MLT     ')
        else:
            return (' ')
    

    First convert the timestamp values to numbers:

    xx = [mdates.date2num(i) for i in ada[ini:end].index]
    

    and plot

    fig = plt.figure(figsize=(10, 5)) #
    ax1 = fig.add_subplot(111)
    ax1.plot(xx,ada['BLC 73.61'][ini:end])
    # set the major locator ion the month values
    ax1.xaxis.set_major_locator(mdates.MonthLocator(interval=5))
    # use the format difeined in format_func2
    ax1.xaxis.set_major_formatter(plt.FuncFormatter(format_func2))
    ax1.xaxis.set_minor_locator(mdates.HourLocator(interval=2)) 
    ax1.xaxis.set_minor_formatter(plt.FuncFormatter(format_func))