When I try to plot the following data
import pandas as pd
dfx = pd.DataFrame()
dfx['bing'] = [1,2,3,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan]
dfx['bang'] = [np.nan,np.nan,np.nan,4,5,6,np.nan,np.nan,np.nan]
dfx['boo'] = [np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,7,8,9]
dfx.plot()
plt.show()
I get this line with gaps. I want to be able to make use of the different colors for different segments of my line, but would like it to be "connected" as well.
CodePudding user response:
Two possible ideas:
Option 2: Add line to connect the other lines
A bit more work (though there may be a quicker way to construct the "connector" line than the approach I'm using here). Add a column that connects end of one line with start of the next. E.g.:
dfx = pd.DataFrame()
dfx['bing'] = [1,2,3,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan]
dfx['bang'] = [np.nan,np.nan,np.nan,4,5,6,np.nan,np.nan,np.nan]
dfx['boo'] = [np.nan,np.nan,np.nan,np.nan,np.nan,np.nan,7,8,9]
# get index vals end-start: array([2, 3, 5, 6], dtype=int64)
s = dfx.apply(lambda col: (col.first_valid_index(),
col.last_valid_index()))\
.stack().sort_values().to_numpy()[1:-1]
# create extra col with connection btw consecutive lines
dfx['connect'] = dfx.fillna(method='ffill', axis=1).iloc[:,-1]\
.mask(~dfx.index.isin(s))
# print(dfx.connect.to_numpy())
# [nan nan 3. 4. nan 6. 7. nan nan]
fig, ax = plt.subplots(figsize=(12,8))
colors = ['blue','orange','green','black']
for i, col in enumerate(dfx.columns):
if col == 'connect':
# add `label=col` if you want "connect" in the legend as well
ax.plot(dfx[col], colors[i], linestyle='dotted')
else:
ax.plot(dfx[col], colors[i], label=col)
ax.legend()
plt.show()
Result: