Issue
I try to get x and y ticks from 2 plots and share it on the x and y axis. With one plot it works
import matplotlib.pyplot as plt
import matplotlib.dates as md
from datetime import datetime
v1 = datetime.fromisoformat("2022-10-15T23:45:51.159618277Z")
v2 = datetime.fromisoformat("2022-10-16T23:49:51.159618277Z")
v3 = datetime.fromisoformat("2022-10-17T22:25:46.638699435Z")
t_time_values2 = [v1, v2, v3]
datenums = md.date2num(t_time_values2)
y = [30, 15, 45]
# plot lines
ax = plt.gca()
xfmt = md.DateFormatter('%Y-%m-%d %H:%M:%S.%f')
ax.xaxis.set_major_formatter(xfmt)
plt.plot(datenums, y, label="line 1")
ax.set_xticks(datenums)
ax.set_yticks(y)
plt.legend()
plt.show()
But now I try to combine 2 plots, and each x and y tick(from the plot) should be visible on the common x and y axis
I try it with this code, but unfortunately I can not merge the ticks from the 2 plots
import matplotlib.pyplot as plt
import matplotlib.dates as md
from datetime import datetime
v1 = datetime.fromisoformat("2022-10-15T23:45:51.159618277Z")
v2 = datetime.fromisoformat("2022-10-16T23:49:51.159618277Z")
v3 = datetime.fromisoformat("2022-10-17T22:25:46.638699435Z")
t_time_values1 = [v1, v2, v3]
datenums1 = md.date2num(t_time_values1)
y1 = [30, 15, 45]
#Plot2
v4 = datetime.fromisoformat("2022-10-15T05:45:51.159618277Z")
v5 = datetime.fromisoformat("2022-10-16T05:49:51.159618277Z")
v6 = datetime.fromisoformat("2022-10-17T02:25:46.638699435Z")
t_time_values2 = [v4, v5, v6]
datenums2 = md.date2num(t_time_values2)
y2 = [78, 25, 55]
# plot lines
ax = plt.gca()
xfmt = md.DateFormatter('%Y-%m-%d %H:%M:%S.%f')
ax.xaxis.set_major_formatter(xfmt)
plt.plot(datenums1, y1, label="line 1")
plt.plot(datenums2, y2, label="line 2")
ax.set_xticks(datenums1)
ax.set_xticks(datenums2)
ax.set_yticks(y1)
ax.set_yticks(y2)
plt.legend()
plt.show()
Solution
Please see how ax.set_xticks
and ax.set_yticks
work.
You are getting the current output because of your code: it is explicitly setting the x-ticks according to datenums2 because how you have asked it to at line number 28: ax.set_xticks(datenums2)
.
This is undoing the expected result from the line written just before that, which is ax.set_xticks(datenums1).
Similar thing is happening with ax.set_yticks
: it's only plotting yticks using y2.
There are different ways to handle this issue :
- Let matplotlib take care of the tick labels and positions:
2. Define only y-ticks' locations and let maplotlib take care of y-ticks' labels, x-ticks' locations and their labels: 3. Define both x-ticks' and y-ticks' locations and let maplotlib take care of x-ticks' and y-ticks' labels. I am using different time but the dates are the same as provided in the question, please see the code below:
4. The best way to arrange xticks would be to properly format x-tick labels and let matplotlib take care of y-ticks:
import matplotlib.pyplot as plt
import matplotlib.dates as md
from datetime import datetime
v1 = datetime.fromisoformat("2022-10-15T23:45:51")
v2 = datetime.fromisoformat("2022-10-16T23:49:51")
v3 = datetime.fromisoformat("2022-10-17T22:25:46")
t_time_values1 = [v1, v2, v3]
datenums1 = md.date2num(t_time_values1)
y1 = [30, 15, 45]
#Plot2
v4 = datetime.fromisoformat("2022-10-15T05:45:51")
v5 = datetime.fromisoformat("2022-10-16T05:49:51")
v6 = datetime.fromisoformat("2022-10-17T02:25:46")
t_time_values2 = [v4, v5, v6]
datenums2 = md.date2num(t_time_values2)
y2 = [78, 25, 55]
# plot lines
ax = plt.gca()
xfmt = md.DateFormatter('%Y-%m-%d %H:%M:%S.%f')
ax.xaxis.set_major_formatter(xfmt)
plt.plot(datenums1, y1, label="line 1")
plt.plot(datenums2, y2, label="line 2")
# Code above this comment will remain same for figure 2 and 3
plt.legend()
plt.show()
Code for figure 2:
# Add this in the code for figure 1
ax.set_yticks(y1 + y2)
y1 + y2 creates a list from the elements of y1 and y2.
Code for figure 3:
# Add these lines in the code for figure 1
ax.set_xticks(datenums1.tolist() + datenums2.tolist())
ax.set_yticks(y1 + y2)
datenums1 and datenums2 are numpy arrays, so if we try datenums1 + datenums2, it will just give another numpy array by doing an element-wise addition. That's why, we convert them to list first to get a list of x-ticks' locations.
Code for figure 4:
.
.
.
# plot lines
ax = plt.gca()
# xfmt = md.DateFormatter('%Y-%m-%d %H:%M:%S.%f')
# ax.xaxis.set_major_formatter(xfmt)
plt.plot(datenums1, y1, label="line 1")
plt.plot(datenums2, y2, label="line 2")
# Formatting of xticklabels
xticks = datenums1.tolist() + datenums2.tolist()
labels = t_time_values1 + t_time_values2
def format_xlabels(x):
fmt = '%Y-%m-%d %H:%M:%S.%f'
label = x.strftime(fmt)
label = label.rstrip("0") # Optional
label = label.rstrip(".") # Optional
return(label)
xlabels = [format_xlabels(i) for i in labels]
ax.set_xticks(xticks, labels=xlabels)
xlabels = ax.get_xticklabels()
plt.setp(xlabels, rotation=45, horizontalalignment='right')
plt.legend()
plt.tight_layout() # Important for xtick labels to show up in the figure
plt.show()
Please check the function my_format_function
from here which I used to create the function format_xlabels
in the code above.
Answered By - medium-dimensional
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.