Skip to content
Advertisement

only last curve with marker is plotted in for loop – how to plot all markers

I have created a list of markers in which each marker is used to show the max value of that curve. (4 curves -> 4 markers)

Somehow I cannot get all the markers to appear in the plot. It seems only the first marker in the for loop is plotted.

import pandas as pd
from matplotlib import pyplot as plt
import numpy as np


df0 = pd.DataFrame(np.random.randint(0,1000,size=(18, 4)), columns=list('ABCD'))
#df0 = pd.read_excel("est.xlsx")
df0.plot()
mylist = list(df0)
# df=df.astype(float)

mrkr = ['o', '.', 'v', 'x']
mrkr_df = pd.DataFrame(mrkr)

idx_mx_vals = []
for i in range(len(mylist)):
    if df0[mylist[i]][0] > 0:
        idx_mx_vals.append(df0[mylist[i]].idxmax())
    else:
        idx_mx_vals.append(df0[mylist[i]].idxmin())

mx_vals = []
for i in range(len(mylist)):
    if df0[mylist[i]][0] > 0:
        mx_vals.append(df0[mylist[i]].max())
    else:
        mx_vals.append(df0[mylist[i]].min())

d = {}
for i in range(len(mylist)):
    d[df0.columns[i]] = [idx_mx_vals[i], mx_vals[i], mrkr[i]]
df = pd.DataFrame(d)
print(df)

for col in range(len(mrkr_df.columns)):
    plt.plot(df.iloc[0, col], df.iloc[1, col], marker=mrkr_df.iloc[2, col],
             markersize=20)

Advertisement

Answer

You can greatly simplify your code, use idxmax directly on the absolute values as a vectorial call. You also do not need to create intermediates DataFrames to hold the idxmax/max (I still showed a simpler method to compute it).

Here is a simple version to plot your curves and the greatest extremum. I also added the same color to match the lines.

import pandas as pd
from matplotlib import pyplot as plt
import numpy as np

np.random.seed(0)
df0 = pd.DataFrame(np.random.randint(0,1000,size=(18, 4)), columns=list('ABCD'))
#df0 = pd.read_excel("est.xlsx")
ax = df0.plot()

mrkr = ['o', '.', 'v', 'x']
mrkr_df = pd.DataFrame(mrkr)

idx_mx_vals = df0.abs().idxmax().to_list()

mx_vals = df0.to_numpy()[idx_mx_vals, np.arange(len(idx_mx_vals))].tolist()

# not needed
#df = pd.DataFrame(dict(zip(df, zip(idx_mx_vals, mx_vals, mrkr))))

for x, y, m, line in zip(idx_mx_vals, mx_vals, mrkr, ax.lines):
    ax.plot(x, y, marker=m, c=line.get_color(), markersize=20)

output:

plot with markers

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement