【问题标题】:Jupyter - merge 2 plots with same x-axisJupyter - 合并 2 个具有相同 x 轴的图
【发布时间】:2018-06-07 23:34:49
【问题描述】:

我使用 Jupyter 的 matplotlib 生成了以下图。 这些图具有相同的 x 轴,因此我想将它们合并,即两个图都有一个共同的 x 轴。

这是我使用的代码。如何将结果集成到这段代码中?

import numpy as np 
import pandas as pd
from scipy.optimize import curve_fit    
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator
from matplotlib.colors import ListedColormap, LinearSegmentedColormap

file1 = '1.dat'
file2 = '1SED.dat'

data1 = pd.read_csv(file1, delimiter='\s+', header=None, engine='python')
data1.columns = ['Wavelength','Obs.Flux','Obs.Error','Flux','Error','FluxMod','Fitted','Excess','(F-Fm)']

data2 = pd.read_csv(file2, delimiter='\s+', header=None, engine='python')
data2.columns = ['wave','cflux']


def fit_data():

fig = plt.figure(1,figsize=(10,9))

plt.subplot(211)
np.linspace(1000,3E4)
plt.plot(data2['wave'], data2['cflux'],   color='cornflowerblue', linestyle= '-', lw=0.5)
plt.scatter(data1['Wavelength'], data1['Obs.Flux'],  marker='o', color='red', s=75)

#plt.xlabel('$\lambda (\AA)$',size=15)
plt.ylabel('$F_{\lambda} (erg/cm^{2}/s/\AA)$',size=15)
plt.yscale('log')
plt.xscale('log')
plt.ylim(1E-18,4E-17)
plt.xlim(1000,2E4)
plt.title('Star No. 1')

plt.subplot(212)
plt.plot(data1['Wavelength'], data1['(F-Fm)'],  marker='o', color='red')
plt.plot(data1['Wavelength'], data1['(F-Fm)'],  linestyle='-', color='red', lw=1.5)
plt.xlabel('$\lambda (\AA)$',size=15)
plt.xscale('log')

plt.savefig("1SED")

plt.show()
plt.close()

fit_data()

我尝试使用您建议的编辑并收到以下错误

TypeError                                 Traceback (most recent call last)
<ipython-input-8-d43e496e030f> in <module>()
     32     plt.close()
     33 
---> 34 fit_data()


<ipython-input-8-d43e496e030f> in fit_data()
     16 #... other commands to be applied on ax1
     17 
---> 18     ax2 = fig.add_subplot(212, sharex=True)
     19     ax2.plot(data1['Wavelength'], data1['(F-Fm)'],  marker='o', color='red')
     20     ax2.plot(data1['Wavelength'], data1['(F-Fm)'],  linestyle='-', color='red', lw=1.5)

~/anaconda3/lib/python3.6/site-packages/matplotlib/figure.py in add_subplot(self, *args, **kwargs)
   1072                     self._axstack.remove(ax)
   1073 
-> 1074             a = subplot_class_factory(projection_class)(self, *args, **kwargs)
   1075 
   1076         self._axstack.add(key, a)

~/anaconda3/lib/python3.6/site-packages/matplotlib/axes/_subplots.py in __init__(self, fig, *args, **kwargs)
     71 
     72         # _axes_class is set in the subplot_class_factory
---> 73         self._axes_class.__init__(self, fig, self.figbox, **kwargs)
     74 
     75     def __reduce__(self):

~/anaconda3/lib/python3.6/site-packages/matplotlib/axes/_base.py in __init__(self, fig, rect, facecolor, frameon, sharex, sharey, label, xscale, yscale, axisbg, **kwargs)
    496         self._sharey = sharey
    497         if sharex is not None:
--> 498             self._shared_x_axes.join(self, sharex)
    499             if sharex._adjustable == 'box':
    500                 sharex._adjustable = 'datalim'

~/anaconda3/lib/python3.6/site-packages/matplotlib/cbook/__init__.py in join(self, a, *args)
   1493 
   1494         for arg in args:
-> 1495             set_b = mapping.get(ref(arg))
   1496             if set_b is None:
   1497                 set_a.append(ref(arg))

TypeError: cannot create weak reference to 'bool' object

【问题讨论】:

标签: python matplotlib plot jupyter-notebook


【解决方案1】:

为了像这样个性化子图,matplotlib 的面向对象的 API 使代码更加简单。

你已经有fig = plt.figure(...,那么你需要做ax1 = fig.add_subplot(211)并修改大多数调用的方法,一般来说,在名称前添加一个set_(即xlabel、yscale、title... ) 有效,如有疑问,请咨询axes class documentation

此外,可以使用我评论的其他链接的答案。与上面代码的主要区别在于使用sharex=True 来强制两个子图具有相同的x 轴,并在绘制后使用setpsubplots_adjust 删除标签和空格。

因此,代码如下所示:

fig = plt.figure(1,figsize=(10,9))

ax1= fig.add_subplot(211)
ax1.plot(data2['wave'], data2['cflux'],   color='cornflowerblue', linestyle= '-', lw=0.5)
ax1.scatter(data1['Wavelength'], data1['Obs.Flux'],  marker='o', color='red', s=75)

ax1.set_ylabel('$F_{\lambda} (erg/cm^{2}/s/\AA)$',size=15)
ax1.set_yscale('log')
#... other commands to be applied on ax1

ax2 = fig.add_subplot(212, sharex=ax1)
#... other commands to be applied on ax2

plt.setp(ax1.get_xticklabels(), visible=False) # hide labels
fig.subplots_adjust(hspace=0) # remove vertical space between subplots

【讨论】:

  • 我已经尝试了代码,它编译并打印出第一个图,但不是第二个。我已将错误包含在原始问题中
  • @Bryan 哦,对不起,我不知道我为什么写 True。我已经纠正了。它应该是 ax1,以便告诉 matplotlib 应该与谁共享 xaxis
  • 好的。我试图通过删除该语句来编译它并且它有效。
  • 我还有一个问题。我需要在第一个图中添加误差线。使用 TOPCAT 很容易做到这一点。我尝试使用 matplotlib 页面的帮助,但它以错误终止。知道如何修复它吗?
  • 然后只需使用ax1.errorbar() 而不是ax1.scatterax1.plot。这是errorbar方法的文档:matplotlib.org/api/_as_gen/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多