V22 V22 - 15 days ago 6
Python Question

Add a row to xtick labels and change the color

I'm trying to plot two sets of data that occur over different times. My goal is to have two sets of xaxis labels that correspond to that data point at that time in color, with one on top of the other. So far I have this:

import numpy as np
import matplotlib.pyplot as plt

data1 = [4, 5, 3, 6]
data2 = [1, 6, 7, 2]

xlabel = ['2120', '2125', '2129', '2133']
xlabel2 = ['\n 2115', '\n 2118', '\n 2121', '\n 2124']

xticks = np.arange(0, len(data1) ,1)

fig = plt.figure(figsize=[8.0,5.0])
ax = fig.add_subplot(111)
ax.plot(xticks, data1, color='b', label='Data 1')
ax.plot(xticks, data2, color='r', label='Data 2')
xmajor_ticks=np.arange(0,4,1)
ax.set_xticks(xmajor_ticks)
ax.set_xticklabels(xlabel, color='b')
ax.set_xticklabels(xlabel2, color='r')
ax.set_xlim([-0.5,3.5])
ax.set_xlabel('Time')
ax.legend(loc='upper left')
ax.grid()


This is overwriting the first ax.set_xticklabels and only plots the data2 red times. How can I keep the data1 times in blue with the data2 times in red below on the xaxis?

Answer

The problem is that you are indeed overwriting the ticklabels. In order to prevent this, one option is to use another axes object to draw the data from the second plot to. One can do that via ax2 = ax.twiny() which creates another axes linked to the y axis of the first axes. This would now result in labels beeing drawn on top of the plot, which is mostly fine.

Here it is asked to draw labels below the plot as well. Note that the following solution is kind of a hack to get the required behaviour and that is has some drawbacks, like a non-fixed position of the labels when resizing.

import numpy as np
import matplotlib.pyplot as plt

data1 = [4, 5, 3, 6]
data2 = [1, 6, 7, 2]

xlabel = ['2120', '2125', '2129', '2133']
xlabel2 = ['2115', '2118', '2121', '2124']

xticks = np.arange(0, len(data1) ,1)

fig = plt.figure(figsize=[8.0,5.0])
ax = fig.add_subplot(111)
ax2 = ax.twiny()
pl1, = ax.plot(xticks, data1, color='b', label='Data 1')
pl2, = ax2.plot(xticks, data2, color='r', label='Data 2')

ax2.spines['top'].set_position(('axes',-0.1))
ax2.spines['top'].set_visible(False)
ax2.xaxis.set_tick_params(size=0)

xmajor_ticks=np.arange(0,4,1)
ax.set_xticks(xmajor_ticks)
ax2.set_xticks(xmajor_ticks)
ax.set_xticklabels(xlabel, color='b')
ax2.set_xticklabels(xlabel2, color='r')
ax.set_xlim([-0.5,3.5])
ax2.set_xlim([-0.5,3.5])
ax.set_xlabel('Time')             
ax.legend(handles=[pl1, pl2], labels= ['Data 1' ,'Data 2'], loc='upper left')
ax.grid()
plt.show()
Comments