Jupyter - 合并2个相同x轴的图

时间:2018-06-05 15:12:03

标签: python matplotlib plot jupyter-notebook

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

plot 这是我用过的代码。如何将结果集成到此代码中?

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

1 个答案:

答案 0 :(得分: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