层次轴标签化

10
假设我正在查看一个n x n的网格,每个轴上都有动物的标签。但我也对动物之间的群体、亚群等关系感兴趣。例如,我可能有脊椎动物和无脊椎动物,在脊椎动物中可能有哺乳动物和爬行动物等等。(如果重要的话,我特别关注相关矩阵,并且实际上是通过seaborn使用热图...)
我想在matplotlib中绘制这个图表,但希望沿着轴进行层次化标记。所以根据上面的例子,我会有像狗、猫、马、蜥蜴、鳄鱼等的标签,然后第一组从狗到马的标签将是哺乳动物,第二组蜥蜴、鳄鱼等将是爬行动物,这两组再加在一起将有一个更进一步的标签——脊椎动物...
我该如何做到这一点?

2个回答

15

不幸的是,我无法弄清如何禁用次要刻度:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from mpl_toolkits.axes_grid.parasite_axes import SubplotHost

fig1 = plt.figure()
ax1 = SubplotHost(fig1, 111)
fig1.add_subplot(ax1)

# Some data
x = np.arange(1,6)
y = np.random.random(len(x))

# First X-axis
ax1.plot(x, y)
ax1.set_xticks(x)
ax1.set_xticklabels(['dog', 'cat', 'horse', 'lizard', 'crocodile'])
#ax1.xaxis.set_label_text('First X-axis') # Uncomment to label axis
ax1.yaxis.set_label_text("Sample data")

# Second X-axis
ax2 = ax1.twiny()
offset = 0, -25 # Position of the second axis
new_axisline = ax2.get_grid_helper().new_fixed_axis
ax2.axis["bottom"] = new_axisline(loc="bottom", axes=ax2, offset=offset)
ax2.axis["top"].set_visible(False)

ax2.set_xticks([0.0, 0.6, 1.0])
ax2.xaxis.set_major_formatter(ticker.NullFormatter())
ax2.xaxis.set_minor_locator(ticker.FixedLocator([0.3, 0.8]))
ax2.xaxis.set_minor_formatter(ticker.FixedFormatter(['mammal', 'reptiles']))

# Third X-axis
ax3 = ax1.twiny()
offset = 0, -50
new_axisline = ax3.get_grid_helper().new_fixed_axis
ax3.axis["bottom"] = new_axisline(loc="bottom", axes=ax3, offset=offset)
ax3.axis["top"].set_visible(False)

ax3.set_xticks([0.0, 1.0])
ax3.xaxis.set_major_formatter(ticker.NullFormatter())
ax3.xaxis.set_minor_locator(ticker.FixedLocator([0.5]))
ax3.xaxis.set_minor_formatter(ticker.FixedFormatter(['vertebrates']))

ax1.grid(1)
plt.show()

enter image description here


编辑:

  1. 通过将ticksize设置为0来禁用次要刻度(感谢@arnsholt):ax2.axis["bottom"].minor_ticks.set_ticksize(0)

  2. 在最新的matplotlib版本(3.0.0或更高版本)中,需要导入SubplotHost

    from mpl_toolkits.axisartist.parasite_axes import SubplotHost


这太棒了!但是你知道如何在子图中实现吗?我有一些时间序列数据,可以分成不同的类型,我想在线图中添加一个额外的y轴,仅标记组别。 - Stefan Falk
@displayname 我认为,适合您情况的方法是为大子图创建一个独立的轴。请查看https://dev59.com/A2w05IYBdhLWcg3w4125#6981055的第一部分。有一个名为“ax”的大轴,其中关闭了轴线和刻度。要向左移动它,请使用`ax.spines [“left”] .set_position((“axes”,-0.1))`。 - Vadim Shkaberda
1
@displayname 你好,看起来ImportanceOfBeingErnest的解决方案是最好的方法。 - Vadim Shkaberda
1
使用matplotlib版本3.0.2运行此代码会出现错误AttributeError: 'AxesSubplot' object has no attribute 'get_grid_helper'。有什么解决方法吗? - BeardedDork
2
@BeardedDork 你导入错误了。尝试使用 from mpl_toolkits.axisartist.parasite_axes import SubplotHost - Vadim Shkaberda
显示剩余5条评论

9
这是 @Vadim 的回答的稍微更新版本,因为我找到了一种不需要 SubplotHost 的方法来完成这个操作。这样,即使您没有创建子图(例如在使用 seaborn 的 figure-level 函数时),您也可以这样做。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

fig1, ax1 = plt.subplots(1)
# Some data
x = np.arange(1,6)
y = np.random.random(len(x))

# First X-axis
ax1.plot(x, y)
ax1.set_xticks(x)
ax1.set_xticklabels(['dog', 'cat', 'horse', 'lizard', 'crocodile'])
ax1.yaxis.set_label_text("Sample data")

# Second X-axis
ax2 = ax1.twiny()

ax2.spines["bottom"].set_position(("axes", -0.10))
ax2.tick_params('both', length=0, width=0, which='minor')
ax2.tick_params('both', direction='in', which='major')
ax2.xaxis.set_ticks_position("bottom")
ax2.xaxis.set_label_position("bottom")

ax2.set_xticks([0.0, 0.6, 1.0])
ax2.xaxis.set_major_formatter(ticker.NullFormatter())
ax2.xaxis.set_minor_locator(ticker.FixedLocator([0.3, 0.8]))
ax2.xaxis.set_minor_formatter(ticker.FixedFormatter(['mammal', 'reptiles']))

# Third X-axis
ax3 = ax1.twiny()

ax3.spines["bottom"].set_position(("axes", -0.20))
ax3.tick_params('both', length=0, width=0, which='minor')
ax3.tick_params('both', direction='in', which='major')
ax3.xaxis.set_ticks_position("bottom")
ax3.xaxis.set_label_position("bottom")

ax3.set_xticks([0.0, 1.0])
ax3.xaxis.set_major_formatter(ticker.NullFormatter())
ax3.xaxis.set_minor_locator(ticker.FixedLocator([0.5]))
ax3.xaxis.set_minor_formatter(ticker.FixedFormatter(['vertebrates']))

ax1.grid(True)
plt.show()

line plot with hierarchical x axis


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接