Matplotlib共享x轴和颜色条不起作用。

7

在这里输入图片描述我有两个子图,一个是散点图,另一个是柱状图,我希望它们共享x轴。散点图还有一个颜色条。然而,由于两个图的轴不重合,共享x轴似乎无法使用。

fig, (ax, ax2) = plt.subplots(2,1, gridspec_kw = {'height_ratios':[13,2]},figsize=(15,12), sharex=True)

df_plotdata.plot(kind='scatter', ax=ax, x='index_cancer', y='index_g', s=df_plotdata['freq1']*50, c=df_plotdata['freq2'], cmap=cmap)

df2.plot(ax=ax2, x='index_cancer', y='freq', kind = 'bar')

我意识到颜色条存在问题,尝试移动颜色条似乎不起作用。我也无法摆脱它。 - Preethi
1
Sharex 意味着轴限制相同且轴已同步。这并不意味着它们重叠在一起。这取决于你如何创建色条。如果人们在问题中提供了 [mcve],那么将其复制并更改以轻松回答他们的问题,这不是很好吗? - ImportanceOfBeingErnest
3个回答

11

Sharex 表示轴限制相同且轴已同步。这并不意味着它们重叠在一起。这取决于您如何创建色条。

Pandas 散点图创建的色条与 matplotlib 中的任何标准色条一样,都是通过从与其相关联的轴上取走一部分空间来创建的。因此,此轴比网格中的其他轴小。

您可以选择以下选项:

  • 缩小网格中的其他轴以与散点图轴相同的量。
    这可以通过使用第一个轴的位置并相应地设置第二个轴的位置来完成,使用 ax.get_position()ax.set_postion()

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import itertools as it

xy = list( it.product( range(10), range(10) ) )
df = pd.DataFrame( xy, columns=['x','y'] )
df['score'] = np.random.random( 100 )

kw = {'height_ratios':[13,2]}
fig, (ax,ax2) = plt.subplots(2,1,  gridspec_kw=kw, sharex=True)

df.plot(kind='scatter', x='x',  y='y', c='score', s=100, cmap="PuRd",
          ax=ax, colorbar=True)
df.groupby("x").mean().plot(kind = 'bar', y='score',ax=ax2, legend=False)

ax2.legend(bbox_to_anchor=(1.03,0),loc=3)

pos = ax.get_position()
pos2 = ax2.get_position()
ax2.set_position([pos.x0,pos2.y0,pos.width,pos2.height])

plt.show()

enter image description here

  • 创建一个包括颜色条轴的网格。
    在这种情况下,您可以创建一个 4x4 的网格,并将颜色条添加到其右上角的轴中。这需要向 fig.colorbar() 提供散点图并为颜色条指定一个轴。

fig.colorbar(ax.collections[0], cax=cax)       

然后移除不需要的右下轴线 (ax.axis("off"))。如果需要的话,您仍然可以通过 ax2.get_shared_x_axes().join(ax, ax2) 来共享坐标轴。

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import itertools as it


xy = list( it.product( range(10), range(10) ) )
df = pd.DataFrame( xy, columns=['x','y'] )
df['score'] = np.random.random( 100 )

kw = {'height_ratios':[13,2], "width_ratios":[95,5]}
fig, ((ax, cax),(ax2,aux)) = plt.subplots(2,2,  gridspec_kw=kw)

df.plot(kind='scatter', x='x',  y='y', c='score', s=80, cmap="PuRd",
         ax=ax,colorbar=False)
df.groupby("x").mean().plot(kind = 'bar', y='score',ax=ax2, legend=False)

fig.colorbar(ax.collections[0], cax=cax, label="score")
aux.axis("off")
ax2.legend(bbox_to_anchor=(1.03,0),loc=3)
ax2.get_shared_x_axes().join(ax, ax2)
ax.tick_params(axis="x", labelbottom=0)
ax.set_xlabel("")

plt.show()

这里输入图片描述


5

根据ImportanceOfBeingErnest的回答,下面的两个函数可以对齐坐标轴:

def align_axis_x(ax, ax_target):
    """Make x-axis of `ax` aligned with `ax_target` in figure"""
    posn_old, posn_target = ax.get_position(), ax_target.get_position()
    ax.set_position([posn_target.x0, posn_old.y0, posn_target.width, posn_old.height])

def align_axis_y(ax, ax_target):
    """Make y-axis of `ax` aligned with `ax_target` in figure"""
    posn_old, posn_target = ax.get_position(), ax_target.get_position()
    ax.set_position([posn_old.x0, posn_target.y0, posn_old.width, posn_target.height])

0

使用Matplotlib工具包(包含在Matplotlib中)

我想添加一个替代当前答案的方法,即使用Matplotlib工具包中的make_axes_locatable函数。这个函数默认情况下优化了空间的使用。如果您有一个复杂的子图配置,例如使用gridspec的几个子图,这将产生很大的差异。

使用示例

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import itertools as it
from mpl_toolkits.axes_grid1 import make_axes_locatable

# create some data
xy = list(it.product(range(16), range(16)))
df = pd.DataFrame(xy, columns=["x", "y"])
df["bubles"] = np.random.random(256)

# create figure and main axis
fig = plt.figure(figsize=(10,6))
ax = plt.gca()

# create a divider from make_axes_locatable
divider = make_axes_locatable(ax)

# append a new axis on the bottom whose size is 15% of the size of the main ax
bax = divider.append_axes("bottom", size="15%", pad=.05)

# append axis on the right for colourbar (size = 5%)
cax = divider.append_axes("right", size="5%", pad=.05)

cm = "plasma" # defining colourmap
sm = plt.cm.ScalarMappable(cmap=cm)

# plotting on main axis
p1 = df.plot(kind='scatter', x='x',  y='y', c='bubles', s=df["bubles"]*200, cmap=cm,
          ax=ax, colorbar=False)

# attaching colourbar to the axis at the right
plt.colorbar(sm, cax=cax)

# plotting on the adjascent axis (bottom)
p2 = df.groupby("x").mean().plot(kind = 'bar', y='bubles',ax=bax, legend=False)

# synchronizing plots on the x-axis
p2.sharex(p1)

# inserting some legend
bax.legend(bbox_to_anchor=(1.03,0),loc=3)

plt.show()

上面的代码会产生如下图所示的结果: Result with make_axes_locatable

在下面的 GIF 中可以看到 sharex 对两个 x 轴的同步效果:

Effect of sharex on the synchronization of the axes


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