Align line graph to xticks on dual axis plot with heatmap

陌路散爱 提交于 2020-06-27 16:43:34

问题


I'm trying to plot a line graph and a heatmap on a dual axis plot. This is what I'm getting:

As you can see, the line graph isn't aligned to the xticks due to the presence of the heatmap, which centers the xticks. How can I shift the line graph to the right by 0.5 so that the data points on the line graph correctly correspond to the xticks?

Below is my code:

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

data1 = np.random.random((10, 10))
data2 = np.random.random((10))

f, ax = plt.subplots(figsize=(11, 9))
plt.tick_params(bottom='on')
ax = sns.heatmap(data1, cmap=sns.color_palette("Greens", 5))
ax2 = plt.twinx()
sns.lineplot(data=data2, linewidth=5, ax=ax2)
ax.axis('tight')

plt.show()

回答1:


Below is one way of doing it.

Explanation: The twin axis instance ax2 has only one line plotted using sns.lineplot. You extract that line object first. Then you just update (shift) the x-data of that line to the right by 0.5 as you wanted. The line.get_xdata() returns you an array of x-values and you simply add 0.5 in a vectorized manner followed by applying the changes using line.set_xdata. Add the following lines after your sns.lineplot() command.

line = ax2.lines[0] # get the line
line.set_xdata(line.get_xdata() + 0.5)




回答2:


The problem is not the lineplot, it's the heatmap which shows ticks at the wrong positions[*]. You may directly use a matplotlib imshow plot instead, where everything works correctly.

import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

data1 = np.random.random((10, 10))
data2 = np.random.random((10))

f, ax = plt.subplots(figsize=(11, 9))
plt.tick_params(bottom='on')

im = ax.imshow(data1, cmap=plt.get_cmap("Greens",5), aspect="auto")
f.colorbar(im)

ax2 = plt.twinx()
sns.lineplot(data=data2, linewidth=5, ax=ax2)
ax.axis('tight')

plt.show()


[*] By "wrong position" I mean that the ticks do not appear at the position on the axes that they seem to label. I.e. the data units of the ticks are not identical to the values shown in the labels.

In case of the heatmap being plotted to ax, printing

print(*ax.get_xticklabels())

results in

Text(0.5, 0, '0') Text(1.5, 0, '1') Text(2.5, 0, '2') Text(3.5, 0, '3') Text(4.5, 0, '4') Text(5.5, 0, '5') Text(6.5, 0, '6') Text(7.5, 0, '7') Text(8.5, 0, '8') Text(9.5, 0, '9')

Here you can see that the first ticklabel is positionned at x=0.5, but shows '0' as label. I.e. all positions are shifted by 0.5 compared to their labels.

In case of the imshow plot, (after drawing the plot, f.canvas.draw()), the printed labels are

Text(-2.0, 0, '-2') Text(0.0, 0, '0') Text(2.0, 0, '2') Text(4.0, 0, '4') Text(6.0, 0, '6') Text(8.0, 0, '8') Text(10.0, 0, '10')

Here labels and positions are consistent.



来源:https://stackoverflow.com/questions/52781245/align-line-graph-to-xticks-on-dual-axis-plot-with-heatmap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!