我有两个不同的数据帧,每个数据帧都有19个变量,我正在绘制一个多图,每个变量的直方图如下:
fig, ax = plt.subplots(figsize=(19,10), dpi=50)
dataframe1.hist(ax=ax, layout=(3,7), alpha=0.5)
fig, ax = plt.subplots(figsize=(19,10), dpi=50)
dataframe2.hist(ax=ax, layout=(3,7), alpha=0.5)
这将产生两个带有19个直方图的图像。我想尝试的是在同一子图中仅绘制一张带有共享直方图的图像。
我尝试过:
fig, ax = plt.subplots(figsize=(19,10), dpi=50)
dataframe1.hist(ax=ax, layout=(3,7), alpha=0.5, label='x')
dataframe2.hist(ax=ax, layout=(3,7), alpha=0.5, label='y', color='red')
但它唯一的一幅画是最后一幅。 这是一个类似的示例:Plot two histograms at the same time with matplotlib,但如何将其应用于19个子图中的两个?
任何想法都将受到欢迎,谢谢!!
P.S:我目前正在将Jupyter Notebook与%matplotlib notebook 选项一起使用
答案 0 :(得分:3)
您的问题是,您实际上需要21(3x7)时,在Axes
调用中仅创建一个plt.subplots
对象。由于提供的子图的数量与请求的子图的数量不匹配,因此熊猫会创建新的子图。由于这种情况发生了两次,因此您只会看到第二组直方图。
您可以完全忽略对subplots
的呼叫,让熊猫来完成所有工作。调用hist
返回所需的所有子图,然后可以在第二次调用hist
中使用。
编辑:
我意识到,如果所需的绘图数量实际上不等于网格单元的数量(在这种情况下为3x9 = 21),则必须准确传递您实际要绘制的子图的数量案例19)。但是,对df.hist
的调用返回每个网格单元(即21)的子图,并且显然隐藏了未使用的网格。因此,您只需将所有返回的子图的子集传递给对hist
的第二次调用。最简单的方法是将2d子图数组转换为1d数组,然后将该数组切片,例如使用`axes.ravel()[:19]。我相应地编辑了代码:
import numpy as np
from matplotlib import pyplot as plt
import pandas as pd
length=19
loc = np.random.randint(0,50,size=length)
scale = np.random.rand(length)*10
dist = np.random.normal(loc=loc, scale=scale, size=(100,length))
df1 = pd.DataFrame(data=list(dist))
axes = df1.hist(layout=(3,7), alpha=0.5, label='x')
loc = np.random.randint(0,50,size=length)
scale = np.random.rand(length)*10
dist = np.random.normal(loc=loc, scale=scale, size=(100,length))
df2 = pd.DataFrame(data=list(dist))
df2.hist(ax=axes.ravel()[:length], layout=(3,7), alpha=0.5, label='x',color='r')
plt.show()
这将产生如下输出:
答案 1 :(得分:1)
调用subplots
时,可以指定所需的行数和列数。在您的情况下,您需要3行7列。但是,.plot
会困扰您的数据帧有21个轴,但只有19个轴。因此,取而代之的是,我们将轴拼合为列表并转换为列表,这将使我们能够通过.pop()
fig, axes = plt.subplots(figsize=(19,10), dpi=50, nrows=3, ncols=7)
flat_axes = list(axes.reshape(-1))
fig.delaxes(flat_axes.pop(-1))
fig.delaxes(flat_axes.pop(-1))
dataframe1.hist(ax=flat_axes, alpha=0.5, label='x')
dataframe2.hist(ax=flat_axes, alpha=0.5, label='x',color='r')