我正在尝试可视化名称同现矩阵。这个版本可以用:
import pandas as pd
import numpy as np
import string
import matplotlib.pyplot as plt
n = 10
names = ['Long Name ' + suffix for suffix in string.ascii_uppercase[:n]]
df = pd.DataFrame(np.random.randint(0, 100, size=(n,n)),
columns=names, index=names)
fig = plt.figure()
ax = plt.gca()
im = ax.matshow(df, interpolation='none')
fig.colorbar(im)
ax.set_xticks(np.arange(n))
ax.set_xticklabels(names)
ax.set_yticks(np.arange(n))
ax.set_yticklabels(names)
ax.xaxis.set_ticks_position("bottom")
plt.setp(ax.get_xticklabels(), rotation=45,
ha="right", rotation_mode="anchor")
for (i,j), z in np.ndenumerate(df):
if z != 0:
ax.text(j, i, str(z), ha="center", va="center")
ax.set_title("Name Co-Occurrences")
fig.tight_layout()
plt.show()
问题在于我拥有的实际矩阵相当大,因此我想在顶部和底部同时显示名称。我尝试使用twiny
来做到这一点:
import pandas as pd
import numpy as np
import string
import matplotlib.pyplot as plt
n = 10
names = ['Long Name ' + suffix for suffix in string.ascii_uppercase[:n]]
df = pd.DataFrame(np.random.randint(0, 100, size=(n,n)),
columns=names, index=names)
fig = plt.figure()
botax = plt.gca()
im = botax.matshow(df, interpolation='none')
fig.colorbar(im)
topax = botax.twiny()
for ax, ha, pos in zip([topax, botax], ["left", "right"], ["top", "bottom"]):
ax.set_xticks(np.arange(n))
ax.set_xticklabels(names)
ax.set_yticks(np.arange(n))
ax.set_yticklabels(names)
ax.xaxis.set_ticks_position(pos)
plt.setp(ax.get_xticklabels(), rotation=45,
ha=ha, va="center", rotation_mode="anchor")
for (i,j), z in np.ndenumerate(df):
if z != 0:
botax.text(j, i, str(z), ha="center", va="center")
botax.set_title("Name Co-Occurrences")
fig.tight_layout()
plt.show()
答案 0 :(得分:2)
为了同时标记轴的底部和顶部,不需要双轴。这可能会使这一切变得容易一些。相反,您可以仅打开底部和顶部的刻度和标签,然后分别旋转和对齐它们。
import pandas as pd
import numpy as np
import string
import matplotlib.pyplot as plt
n = 10
names = ['Long Name ' + suffix for suffix in string.ascii_uppercase[:n]]
df = pd.DataFrame(np.random.randint(0, 100, size=(n,n)),
columns=names, index=names)
fig = plt.figure()
ax = plt.gca()
im = ax.matshow(df, interpolation='none')
fig.colorbar(im)
ax.set_xticks(np.arange(n))
ax.set_xticklabels(names)
ax.set_yticks(np.arange(n))
ax.set_yticklabels(names)
# Set ticks on both sides of axes on
ax.tick_params(axis="x", bottom=True, top=True, labelbottom=True, labeltop=True)
# Rotate and align bottom ticklabels
plt.setp([tick.label1 for tick in ax.xaxis.get_major_ticks()], rotation=45,
ha="right", va="center", rotation_mode="anchor")
# Rotate and align top ticklabels
plt.setp([tick.label2 for tick in ax.xaxis.get_major_ticks()], rotation=45,
ha="left", va="center",rotation_mode="anchor")
ax.set_title("Name Co-Occurrences", pad=55)
fig.tight_layout()
plt.show()
答案 1 :(得分:1)
首先必须将上部x轴的纵横比设置为与下部x轴的纵横比相同。 here已回答了如何做到这一点。然后,您可以使用y=1.3
将标题稍微抬起,使其不与上方的x轴刻度标签重叠。
topax = botax.twiny()
aspect0 = botax.get_aspect()
if aspect0 == 'equal':
aspect0 = 1.0
dy = np.abs(np.diff(botax.get_ylim()))
dx = np.abs(np.diff(botax.get_xlim()))
aspect = aspect0 / (float(dy) / dx)
topax.set_aspect(aspect)
for ax, ha, pos in zip([topax, botax], ["left", "right"], ["top", "bottom"]):
ax.set_xticks(np.arange(n))
.....
.....
botax.set_title("Name Co-Occurrences", y=1.3)