这是我的data_df
col_C col_A col_B col_D
-----------------------------------
8/21/2017 4 1.0 736562.0
8/28/2017 5 2.0 736569.0
9/4/2017 6 4.0 736576.0
9/11/2017 7 5.0 736583.0
9/18/2017 8 6.0 736590.0
10/2/2017 10 7.0 736604.0
2/5/2018 28 125.0 736730.0
我有以下代码,它绘制了一些数据点及其拟合曲线。
xi = np.array(data_df[['col_A']])
yi = np.array(data_df[['col_B']])
plt.figure()
plt.scatter(xi, yi, color = 'r')
x = np.linspace(0, 30, 30)
y= np.exp(x*0.172)
plt.plot(x, y, color = 'g', label = 'exp(t)')
plt.legend()
plt.show()
我还有另一段代码,用相应的日期绘制数据点作为x轴。
import matplotlib
data_df['col_D'] = data_df['col_C'] \
.apply(lambda x: matplotlib.dates.datestr2num(x))
plt.plot_date(data_df[['col_D']], data_df[['col_B']])
plt.show()
现在我尝试将这两个图合并为一个。因此,x轴可以显示[0, 5, 10 ... 30]
和[2017-09, 2017-10 ..., 2018-02]
。以下是组合代码:
xi = np.array(data_df[['col_A']])
yi = np.array(data_df[['col_B']])
plt.figure()
plt.scatter(xi, yi, color = 'r')
x = np.linspace(0, 30, 30)
y= np.exp(x*0.172)
plt.plot(x, y, color = 'g', label = 'exp(t)')
plt.legend()
data_df['col_C'] = data_df['col_D'] \
.apply(lambda x: matplotlib.dates.datestr2num(x))
plt.plot_date(data_df[['col_C']], data_df[['col_B']])
plt.show()
但是,合并后的代码给了我以下错误:
ValueError Traceback (most recent call last)
/usr/local/lib/python3.4/dist-packages/IPython/core/formatters.py in __call__(self, obj)
339 pass
340 else:
--> 341 return printer(obj)
342 # Finally look for special method names
343 method = get_real_method(obj, self.print_method)
/usr/local/lib/python3.4/dist-packages/IPython/core/pylabtools.py in <lambda>(fig)
236
237 if 'png' in formats:
--> 238 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
239 if 'retina' in formats or 'png2x' in formats:
240 png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))
/usr/local/lib/python3.4/dist-packages/IPython/core/pylabtools.py in print_figure(fig, fmt, bbox_inches, **kwargs)
120
121 bytes_io = BytesIO()
--> 122 fig.canvas.print_figure(bytes_io, **kw)
123 data = bytes_io.getvalue()
124 if fmt == 'svg':
/usr/local/lib/python3.4/dist-packages/matplotlib/backend_bases.py in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, **kwargs)
2190 orientation=orientation,
2191 dryrun=True,
-> 2192 **kwargs)
2193 renderer = self.figure._cachedRenderer
2194 bbox_inches = self.figure.get_tightbbox(renderer)
/usr/local/lib/python3.4/dist-packages/matplotlib/backends/backend_agg.py in print_png(self, filename_or_obj, *args, **kwargs)
543
544 def print_png(self, filename_or_obj, *args, **kwargs):
--> 545 FigureCanvasAgg.draw(self)
546 renderer = self.get_renderer()
547 original_dpi = renderer.dpi
/usr/local/lib/python3.4/dist-packages/matplotlib/backends/backend_agg.py in draw(self)
462
463 try:
--> 464 self.figure.draw(self.renderer)
465 finally:
466 RendererAgg.lock.release()
/usr/local/lib/python3.4/dist-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
61 def draw_wrapper(artist, renderer, *args, **kwargs):
62 before(artist, renderer)
---> 63 draw(artist, renderer, *args, **kwargs)
64 after(artist, renderer)
65
/usr/local/lib/python3.4/dist-packages/matplotlib/figure.py in draw(self, renderer)
1141
1142 mimage._draw_list_compositing_images(
-> 1143 renderer, self, dsu, self.suppressComposite)
1144
1145 renderer.close_group('figure')
/usr/local/lib/python3.4/dist-packages/matplotlib/image.py in _draw_list_compositing_images(renderer, parent, dsu, suppress_composite)
137 if not_composite or not has_images:
138 for zorder, a in dsu:
--> 139 a.draw(renderer)
140 else:
141 # Composite any adjacent images together
/usr/local/lib/python3.4/dist-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
61 def draw_wrapper(artist, renderer, *args, **kwargs):
62 before(artist, renderer)
---> 63 draw(artist, renderer, *args, **kwargs)
64 after(artist, renderer)
65
/usr/local/lib/python3.4/dist-packages/matplotlib/axes/_base.py in draw(self, renderer, inframe)
2407 renderer.stop_rasterizing()
2408
-> 2409 mimage._draw_list_compositing_images(renderer, self, dsu)
2410
2411 renderer.close_group('axes')
/usr/local/lib/python3.4/dist-packages/matplotlib/image.py in _draw_list_compositing_images(renderer, parent, dsu, suppress_composite)
137 if not_composite or not has_images:
138 for zorder, a in dsu:
--> 139 a.draw(renderer)
140 else:
141 # Composite any adjacent images together
/usr/local/lib/python3.4/dist-packages/matplotlib/artist.py in draw_wrapper(artist, renderer, *args, **kwargs)
61 def draw_wrapper(artist, renderer, *args, **kwargs):
62 before(artist, renderer)
---> 63 draw(artist, renderer, *args, **kwargs)
64 after(artist, renderer)
65
/usr/local/lib/python3.4/dist-packages/matplotlib/axis.py in draw(self, renderer, *args, **kwargs)
1134 renderer.open_group(__name__)
1135
-> 1136 ticks_to_draw = self._update_ticks(renderer)
1137 ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw,
1138 renderer)
/usr/local/lib/python3.4/dist-packages/matplotlib/axis.py in _update_ticks(self, renderer)
967
968 interval = self.get_view_interval()
--> 969 tick_tups = [t for t in self.iter_ticks()]
970 if self._smart_bounds:
971 # handle inverted limits
/usr/local/lib/python3.4/dist-packages/matplotlib/axis.py in <listcomp>(.0)
967
968 interval = self.get_view_interval()
--> 969 tick_tups = [t for t in self.iter_ticks()]
970 if self._smart_bounds:
971 # handle inverted limits
/usr/local/lib/python3.4/dist-packages/matplotlib/axis.py in iter_ticks(self)
910 Iterate through all of the major and minor ticks.
911 """
--> 912 majorLocs = self.major.locator()
913 majorTicks = self.get_major_ticks(len(majorLocs))
914 self.major.formatter.set_locs(majorLocs)
/usr/local/lib/python3.4/dist-packages/matplotlib/dates.py in __call__(self)
981 def __call__(self):
982 'Return the locations of the ticks'
--> 983 self.refresh()
984 return self._locator()
985
/usr/local/lib/python3.4/dist-packages/matplotlib/dates.py in refresh(self)
1001 def refresh(self):
1002 'Refresh internal information based on current limits.'
-> 1003 dmin, dmax = self.viewlim_to_dt()
1004 self._locator = self.get_locator(dmin, dmax)
1005
/usr/local/lib/python3.4/dist-packages/matplotlib/dates.py in viewlim_to_dt(self)
758 vmin, vmax = vmax, vmin
759
--> 760 return num2date(vmin, self.tz), num2date(vmax, self.tz)
761
762 def _get_unit(self):
/usr/local/lib/python3.4/dist-packages/matplotlib/dates.py in num2date(x, tz)
399 tz = _get_rc_timezone()
400 if not cbook.iterable(x):
--> 401 return _from_ordinalf(x, tz)
402 else:
403 x = np.asarray(x)
/usr/local/lib/python3.4/dist-packages/matplotlib/dates.py in _from_ordinalf(x, tz)
252
253 ix = int(x)
--> 254 dt = datetime.datetime.fromordinal(ix).replace(tzinfo=UTC)
255
256 remainder = float(x) - ix
ValueError: ordinal must be >= 1
<matplotlib.figure.Figure at 0x7f65c6f98f28>
知道出了什么问题吗?是否可以在x轴上显示[0, 5, 10 ... 30]
和[2017-09, 2017-10 ..., 2018-02]
?谢谢!
答案 0 :(得分:0)
问题是一个图的轴范围大致为0到30,而另一个图的轴范围大致为736562到736730(这是日期的数字表示。
您可以选择使用双轴并将一个范围映射到另一个范围。然后根据映射设置双轴的极限。
u = u"""col_C col_A col_B col_D
8/21/2017 4 1.0 736562.0
8/28/2017 5 2.0 736569.0
9/4/2017 6 4.0 736576.0
9/11/2017 7 5.0 736583.0
9/18/2017 8 6.0 736590.0
10/2/2017 10 7.0 736604.0
2/5/2018 28 125.0 736730.0"""
import io
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates
df = pd.read_csv(io.StringIO(u), delim_whitespace=True)
xi = np.array(df[['col_A']])
yi = np.array(df[['col_B']])
fig, ax = plt.subplots()
ax.scatter(xi, yi, color = 'r')
x = np.linspace(0, 30, 30)
y= np.exp(x*0.172)
ax.plot(x, y, color = 'g', label = 'exp(t)')
ax.legend()
ax2 = ax.twiny()
df['col_D'] = df['col_C'].apply(lambda x: matplotlib.dates.datestr2num(x))
ax2.plot_date(df[['col_D']], df[['col_B']])
f = lambda x: (df['col_D'].iloc[-1]- df['col_D'].iloc[0])/ \
(xi[-1]-xi[0])*(x-xi[0])+df['col_D'].iloc[0]
ax2.set_xlim(f(np.array(ax.get_xlim())))
plt.show()
如果您愿意,可以将alpha=0
添加到第二个图中以隐藏它。