如何使用 matplotlib 从 ROOT 模拟 Draw('same')
How to mimic the Draw('same') from ROOT with matplotlib
我有一个来自 ROOT 的用例,我无法用 matplotlib 重现。这是一个最小的例子
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
dist1x = np.random.normal(5, 0.05, 10_000)
dist1y = np.random.normal(5, 0.05, 10_000)
dist2x = np.random.normal(15, 0.05, 10_000)
dist2y = np.random.normal(15, 0.05, 10_000)
ax.hist2d(dist1x, dist1y, bins=100, cmap='viridis')
ax.hist2d(dist2x, dist2y, bins=100, cmap='viridis')
plt.show()
输出为
有了ROOT可以做到:
TCanvas *c1 = new TCanvas("c1","c1");
TH1D *h1 = new TH1D("h1","h1",500,-5,5);
h1->FillRandom("gaus");
TH1D *h2 = new TH1D("h2","h2",500,-5,5);
h2->FillRandom("gaus");
h1->Draw();
h2->Draw("SAME");
并且两个直方图会共享canvas、轴等。为什么在同一张图中绘制两个直方图只显示最后一个?如何重现 ROOT 行为?
我认为预期的行为是绘制两个直方图的总和。您可以通过在绘图之前连接数组来做到这一点:
ax.hist2d(np.concatenate([dist1x, dist2x]),
np.concatenate([dist1y, dist2y]),
bins=100, cmap='viridis')
(我稍微修改了数字,以确保两个斑点重叠。)
SAME
和 TH2F
在 ROOT 中的默认行为可能是不可取的。
第二个直方图绘制覆盖另一个直方图,覆盖 bin 的填充颜色。如果第二个直方图中至少有一个事件,则第一个直方图中的信息将在每个单元格中被丢弃。
要重现此行为,我建议使用 numpy.histogram2d
。如果第二个直方图中有条目,则将第一个直方图的 bin 设置为零,然后绘制两者的总和。
bins = np.linspace(0, 20, 100), np.linspace(0, 20, 100)
hist1, _, _ = np.histogram2d(dist1x, dist1y, bins=bins)
hist2, _, _ = np.histogram2d(dist2x, dist2y, bins=bins)
hist1[hist2 > 0] = 0
sum_hist = hist1 + hist2
plt.pcolormesh(*bins, sum_hist)
如果两个直方图没有任何共同填充的 bin,则这两个行为是相同的。
我有一个来自 ROOT 的用例,我无法用 matplotlib 重现。这是一个最小的例子
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
dist1x = np.random.normal(5, 0.05, 10_000)
dist1y = np.random.normal(5, 0.05, 10_000)
dist2x = np.random.normal(15, 0.05, 10_000)
dist2y = np.random.normal(15, 0.05, 10_000)
ax.hist2d(dist1x, dist1y, bins=100, cmap='viridis')
ax.hist2d(dist2x, dist2y, bins=100, cmap='viridis')
plt.show()
输出为
有了ROOT可以做到:
TCanvas *c1 = new TCanvas("c1","c1");
TH1D *h1 = new TH1D("h1","h1",500,-5,5);
h1->FillRandom("gaus");
TH1D *h2 = new TH1D("h2","h2",500,-5,5);
h2->FillRandom("gaus");
h1->Draw();
h2->Draw("SAME");
并且两个直方图会共享canvas、轴等。为什么在同一张图中绘制两个直方图只显示最后一个?如何重现 ROOT 行为?
我认为预期的行为是绘制两个直方图的总和。您可以通过在绘图之前连接数组来做到这一点:
ax.hist2d(np.concatenate([dist1x, dist2x]),
np.concatenate([dist1y, dist2y]),
bins=100, cmap='viridis')
(我稍微修改了数字,以确保两个斑点重叠。)
SAME
和 TH2F
在 ROOT 中的默认行为可能是不可取的。
第二个直方图绘制覆盖另一个直方图,覆盖 bin 的填充颜色。如果第二个直方图中至少有一个事件,则第一个直方图中的信息将在每个单元格中被丢弃。
要重现此行为,我建议使用 numpy.histogram2d
。如果第二个直方图中有条目,则将第一个直方图的 bin 设置为零,然后绘制两者的总和。
bins = np.linspace(0, 20, 100), np.linspace(0, 20, 100)
hist1, _, _ = np.histogram2d(dist1x, dist1y, bins=bins)
hist2, _, _ = np.histogram2d(dist2x, dist2y, bins=bins)
hist1[hist2 > 0] = 0
sum_hist = hist1 + hist2
plt.pcolormesh(*bins, sum_hist)
如果两个直方图没有任何共同填充的 bin,则这两个行为是相同的。