0

I have 2 dfs. One of them has data for a month. Another one, averages for the past quarters. I wanna plot the averages in front of the monthly data. How can I do it? Please note that I am trying to plot averages as dots and monthly as line chart.

So far my best result was achieved by ax1=ax.twiny(), but still not ideal result as data point appear in throughout the chart, rather than just in front.

import pandas as pd
import numpy as np 
import matplotlib.dates as mdates
from matplotlib.ticker import ScalarFormatter, FormatStrFormatter, FuncFormatter
import matplotlib.ticker as ticker
import matplotlib.pyplot as plt 

date_base = pd.date_range(start='1/1/2018', end='1/30/2018')
df_base = pd.DataFrame(np.random.randn(30,4), columns=list("ABCD"), index=date_base)

date_ext = pd.date_range(start='1/1/2017', end='1/1/2018', freq="Q")
df_ext = pd.DataFrame(np.random.randn(4,4), columns=list("ABCD"), index=date_ext)

def drawChartsPlt(df_base, df_ext):

    fig = plt.figure(figsize=(10,5))
    ax = fig.add_subplot(111)
    number_of_plots = len(df_base.columns)
    LINE_STYLES = ['-', '--', '-.', 'dotted']

    colormap = plt.cm.nipy_spectral
    ax.set_prop_cycle("color", [colormap(i) for i in np.linspace(0,1,number_of_plots)])

    date_base = df_base.index
    date_base = [i.strftime("%Y-%m-%d") for i in date_base]

    q_ends = df_ext.index
    q_ends = [i.strftime("%Y-%m-%d") for i in q_ends]

    date_base.insert(0, "") #to shift xticks so they match chart
    date_base += q_ends

    for i in range(number_of_plots):
        df_base.ix[:-3, df_base.columns[i]].plot(kind="line", linestyle=LINE_STYLES[i%2], subplots=False, ax=ax)

    #ax.set_xticks(date_base)
    #ax.set_xticklabels(date_base)
    # ax.xaxis.set_major_locator(ticker.MultipleLocator(20))
    ax.xaxis.set_major_locator(ticker.LinearLocator(len(date_base)))
    ax.xaxis.set_major_formatter(plt.FixedFormatter(date_base))
    fig.autofmt_xdate()
    # ax1=ax.twinx()
    ax1=ax.twiny()
    ax1.set_prop_cycle("color", [colormap(i) for i in np.linspace(0,1,number_of_plots)])

    for i in range(len(df_ext.columns)):
        ax1.scatter(x=df_ext.index, y=df_ext[df_ext.columns[i]])
    ax.set_title("Test")

    #plt.minorticks_off())
    ax.minorticks_off()
    #ax1.minorticks_off()
    #ax1.set_xticklabels(date_base)
    #ax1.set_xticklabels(q_ends)
    ax.legend(loc="center left", bbox_to_anchor=(1,0.5))

    ax.xaxis.label.set_size(12)
    plt.xlabel("TEST X Label")
    plt.ylabel("TEST Y Label")
    ax1.set_xlabel("Quarters")

    plt.show()

drawChartsPlt(df_base, df_ext)
Biarys
  • 1,065
  • 1
  • 10
  • 22

1 Answers1

0

The way I ended up coding it is by saving quarterly index of df_ext to a temp variable, overwriting it with dates that are close to df_base.index using pd.date_range(start=df_base.index[-1], periods=len(df_ext), freq='D'), and the finally setting the dates that I need with ax.set_xticklabels(list(date_base)+list(date_ext)).

It looks like it could be achieved using broken axes as indicated Break // in x axis of matplotlib and Python/Matplotlib - Is there a way to make a discontinuous axis?, but I haven't tried that solution.

Biarys
  • 1,065
  • 1
  • 10
  • 22