1

Edit: The graph is fixed now but I am having troubles plotting the legend. It only shows legend for 1 of the plots. As seen in the picture below

I am trying to plot a double axis graph with twinx but I am facing some difficulties as seen in the picture below.

Any input is welcomed! If you require any additional information, I am happy to provide them to you.

enter image description here

as compared to the original before plotting z-axis.

enter image description here

I am unsure why my graph is like that as initially before plotting my secondary y axis, (the pink line), the closing value graph can be seen perfectly but now it seems cut.

It may be due to my data as provided below.

Link to testing1.csv: https://filebin.net/ou93iqiinss02l0g

Code I have currently:

# read csv into variable
sg_df_merged = pd.read_csv("testing1.csv", parse_dates=[0], index_col=0)

# define figure
fig = plt.figure()

fig, ax5 = plt.subplots()
ax6 = ax5.twinx()

x = sg_df_merged.index
y = sg_df_merged["Adj Close"]
z = sg_df_merged["Singapore"]

curve1 = ax5.plot(x, y, label="Singapore", color = "c")
curve2 = ax6.plot(x, z, label = "Face Mask Compliance", color = "m")
curves = [curve1, curve2]

# labels for my axis
ax5.set_xlabel("Year")
ax5.set_ylabel("Adjusted Closing Value ($)")
ax6.set_ylabel("% compliance to wearing face mask")
ax5.grid #not sure what this line does actually

# set x-axis values to 45 degree angle
for label in ax5.xaxis.get_ticklabels():
    label.set_rotation(45)
ax5.grid(True, color = "k", linestyle = "-", linewidth = 0.3)

plt.gca().legend(loc='center left', bbox_to_anchor=(1.1, 0.5), title = "Country Index")
plt.show(); 

Initially, I thought it was due to my excel having entire blank lines but I have since removed the rows which can be found here

Also, I have tried to interpolate but somehow it doesn't work. Any suggestions on this is very much welcomed

HOA
  • 111
  • 2
  • 14
  • Please see the updates to the answer. I've added a fix for the legend to include labels for both axes, added markers, to make it clear where the data points are, and updated the code for implementing the xtick rotation. – Trenton McKinney Sep 16 '20 at 20:24
  • 1
    @TrentonMcKinney Wow I really appreciate all your help! Would gladly take you out to coffee if you ever come to Singapore after the pademic ends! – HOA Sep 16 '20 at 21:07
  • 1
    Thanks. Add me on LinkedIn or Twitter. I'll hold you to that if I'm in your neck of the woods. My contact info is in my SO profile. – Trenton McKinney Sep 16 '20 at 21:09

1 Answers1

3
  • Only rows that where all NaN, were dropped. There’s still a lot of rows with NaN.
  • In order for matplotlib to draw connecting lines between two data points, the points must be consecutive.
  • The plot API isn't connecting the data between the NaN values
  • This can be dealt with by converting the pandas.Series to a DataFrame, and using .dropna.
  • See that x has been dropped, because it will not match the index length of y or z. They are shorter after .dropna.
  • y is now a separate dataframe, where .dropna is used.
  • z is also a separate dataframe, where .dropna is used.
  • The x-axis for the plot are the respective indices.
# read csv into variable
sg_df_merged = pd.read_csv("test.csv", parse_dates=[0], index_col=0)

# define figure
fig, ax5 = plt.subplots(figsize=(8, 6))
ax6 = ax5.twinx()

# select specific columns to plot and drop additional NaN
y = pd.DataFrame(sg_df_merged["Adj Close"]).dropna()
z = pd.DataFrame(sg_df_merged["Singapore"]).dropna()

# add plots with markers
curve1 = ax5.plot(y.index, 'Adj Close', data=y, label="Singapore", color = "c", marker='o')
curve2 = ax6.plot(z.index, 'Singapore', data=z, label = "Face Mask Compliance", color = "m", marker='o')

# labels for my axis
ax5.set_xlabel("Year")
ax5.set_ylabel("Adjusted Closing Value ($)")
ax6.set_ylabel("% compliance to wearing face mask")
    
# rotate xticks
ax5.xaxis.set_tick_params(rotation=45)

# add a grid to ax5
ax5.grid(True, color = "k", linestyle = "-", linewidth = 0.3)

# create a legend for both axes
curves = curve1 + curve2
labels = [l.get_label() for l in curves]
ax5.legend(curves, labels, loc='center left', bbox_to_anchor=(1.1, 0.5), title = "Country Index")

plt.show()

enter image description here

Trenton McKinney
  • 56,955
  • 33
  • 144
  • 158