I'm trying to create some scatter plots, with seaborn with a specific area of each plot highlighted in red. However when I add the code for axvspan, it changes the x-axis. This is how the plots look prior to axvspan being applied.
When i apply the line for axvpsan:
fig, (ax0, ax1) = plt.subplots(2,1, figsize=(5,10))
ax0.axvspan("0.4", "0.8", color='red', alpha=0.3, label ='Problem Area')
sns.scatterplot(x='Values_1', y='Values_2', data=df3, color='green', ax=ax0)
sns.scatterplot(x='Values_3', y='Values_4', data=df3, color='green', ax=ax1)
plt.show()
It sends up looking like this:
Ultimately, the red section needs to only cover the data between 0.4 and 0.7, but by altering the x-axis it ends up covering all of it.
Any advice?
The unexpected behavior is resulting from passing the xmin and xmax arguments to matplotlib.pyplot.axvspan as str and not as float.
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd
# generate data
rng = np.random.default_rng(12)
df3 = pd.DataFrame({"Values_2": rng.random(100), "Values_1": np.linspace(0., 0.6, 100)})
fig, ax0 = plt.subplots(1,1, figsize=(6, 4))
ax0.axvspan(0.4, 0.8, color='red', alpha=0.3, label ='Problem Area')
sns.scatterplot(x='Values_1', y='Values_2', data=df3, color='green', ax=ax0)
plt.show()
This gives:
Related
pls I need to add a area color to my code to show a plot similar to this one bellow:
My code is here:
import numpy as np
import pandas as pd
from pandas import DataFrame
import matplotlib.pyplot as plt
from matplotlib import pyplot as plt
df = pd.DataFrame({'Time': [1,2,3,4,5],
'T=0': [0.5,0.16,0,0.25,0],
'T=2': [0.5,0.5,1,1,1],
'T=10': [0.75,0.8,0.85,0.9,0.8]
})
plt.plot( 'Time', 'T=10', data=df, marker='d', color='black', markersize=5, linewidth=1.5, linestyle=':')
plt.plot( 'Time', 'T=2', data=df, marker='^', color='black', markersize=4, linewidth=1.5,linestyle='--')
plt.plot( 'Time', 'T=0', data=df, marker='o', color='black', markersize=4, linewidth=1.5,linestyle='-')
plt.legend()
plt.xlabel("Time")
plt.xticks([1,2,3,4,5])
plt.xlim(0.9, 5.02)
plt.ylabel("Average")
plt.ylim(0, 1.02)
plt.show()
The actual result:
Many thanks.
All you need to do is add the following 3 lines to your code:
plt.fill_between(df['Time'], df['T=0'], alpha = 0.3, color = 'steelblue')
plt.fill_between(df['Time'], df['T=0'], df['T=2'], alpha = 0.3, color = 'yellow')
plt.fill_between(df['Time'], df['T=2'], df['T=10'], alpha = 0.3, color = 'red')
You can also create a legend corresponding to the colors. However, in the case of your graph, since two plot lines cross, it is best to leave the legend assigned to the plot lines rather than the colors (as you have).
With seaborn, I want to plot the kde distribution of 4 different arrays all in one plot.
The problem is that all arrays have different lengths to eachother.
mc_means_TP.shape, mc_means_TN.shape, mc_means_FP.shape, mc_means_FN.shape
> ((3640, 1), (3566, 1), (170, 1), (238, 1))
This makes some workaround necessary, in which I plot them all in one plot by sharing the same axis:
import seaborn as sns
fig, ax = plt.subplots()
sns.kdeplot(data=mc_means_TP, ax=ax, color='red', fill=True)
sns.kdeplot(data=mc_means_TN, ax=ax, color='green', fill=True)
sns.kdeplot(data=mc_means_FP, ax=ax, color='yellow')
sns.kdeplot(data=mc_means_FN, ax=ax, color='purple')
The result looks like this:
Obviously, since they are sharing the same axis, it is not possible to color them differently, they are all colored blue.
I tried solving this with ax.set_prop_cycle(color=['red', 'green', 'blue', 'purple']), but it doesn't work, I guess because Im using the same ax for all plots.
I guess the question breaks down to how to visualize the distribution density of different sized data arrays in one plot?
When arrays with more than one dimension are used, seaborn here ignores the color parameter and only considers the palette. You can either provide a palette (to override the default blue one used in this case), or to squeeze the arrays to be one dimensional:
import numpy as np
import seaborn as sns
from matplotlib import pyplot as plt
mc_means_TP = np.random.normal(10, 1, size=(3640, 1))
mc_means_TN = np.random.normal(20, 1, size=(3566, 1))
mc_means_FP = np.random.normal(12, 1, size=(170, 1))
mc_means_FN = np.random.normal(18, 1, size=(238, 1))
fig, ax = plt.subplots()
sns.kdeplot(data=mc_means_TP.squeeze(), ax=ax, color='red', fill=True, label='means TP')
sns.kdeplot(data=mc_means_TN.squeeze(), ax=ax, color='green', fill=True, label='means TN')
sns.kdeplot(data=mc_means_FP.squeeze(), ax=ax, color='gold', label='means FP')
sns.kdeplot(data=mc_means_FN.squeeze(), ax=ax, color='purple', label='means FN')
ax.legend(bbox_to_anchor=(1.02, 1.02), loc='upper left')
plt.tight_layout()
plt.show()
import numpy as np
import pandas as pd
df = pd.DataFrame({"y" : np.random.rand(20)})
ax = df.iloc[:15,:].plot(ls="-", color="b")
ax2 = ax.twinx() #Create a twin Axes sharing the xaxis
df.iloc[15:,:].plot(ls="--", color="r", ax=ax)
plt.axhline(y=0.5,linestyle="--",animated=True,label="False Alaram")
plt.show()
So, first 15 are trend and last 5 are predictions.
I want different colors for trend and pred in background.
Also, how can i add text "Historic" and "Forecast" on graph.
I believe you're looking for fill_between:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({"y" : np.random.rand(20)})
fig, ax = plt.subplots(figsize=(8,6))
df.iloc[:15,:].plot(ls="-", color="b", ax=ax)
plt.fill_between(df.iloc[:15].index.tolist(), df.iloc[:15].y.tolist(), alpha=.25, color='b')
df.iloc[15:,:].plot(ls="--", color="r", ax=ax)
plt.axhline(y=0.5,linestyle="--", animated=True, label="False Alaram")
plt.fill_between(df.iloc[15:].index.tolist(), df.iloc[15:].y.tolist(), alpha=.25, color='r')
plt.legend()
plt.show()
I'm using matplotlib to produce a plot where I want to show labels on the right and left y-axis. You will notice by running the code that the grid-lines formed by the right-side y-axis appear on top of the plot line, where the left-side lines appear below. I would like them all to appear below the plot. I've tried zorder and set_axisbelow(True) without success.
Example code below:
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np
t = np.linspace(0,5)
x = np.exp(-t)*np.sin(2*t)
fig, ax1 = plt.subplots()
ax1.plot(t, x)
ax2 = ax1.twinx()
ax2.plot(t, x, alpha=0.0)
ax1.set_xticks([0,1,2])
ax1.set_yticks([0.1, 0.2])
ax2.set_yticks([0.3, 0.4, 0.5])
ax1.grid(True, color='lightgray')
ax2.grid(True, color='lightgray')
for a in [ax1, ax2]:
a.spines["top"].set_visible(False)
a.spines["right"].set_visible(False)
a.spines["left"].set_visible(False)
a.spines["bottom"].set_visible(False)
ax1.set_axisbelow(True)
ax2.set_axisbelow(True)
plt.savefig('fig.pdf')
plt.show()
I am learning how to use subplots. For example:
import numpy
import matplotlib.pyplot as plt
plt.figure(1)
plt.subplot(221)
plt.subplot(222)
plt.subplot(223)
plt.show()
plt.close(1)
I am getting 3 subplots in figure1
Now I want to make a large subplot with the other subplots within the first one. I tried:
plt.figure(1)
plt.subplot(111)
plt.subplot(222)
plt.subplot(223)
But the first subplot disappears.
My question: is it possible to overlap subplots?
thank you
If you want a total control of the subplots size and position, use Matplotlib add_axes method instead.
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(6, 4))
ax1 = fig.add_axes([0.1, 0.1, 0.85, 0.85])
ax2 = fig.add_axes([0.4, 0.6, 0.45, 0.3])
ax3 = fig.add_axes([0.6, 0.2, 0.2, 0.65])
ax1.text(0.01, 0.95, "ax1", size=12)
ax2.text(0.05, 0.8, "ax2", size=12)
ax3.text(0.05, 0.9, "ax3", size=12)
plt.show()
You can use mpl_toolkits.axes_grid1.inset_locator.inset_axes to create an inset axes on an existing figure.
I added a print statement at the end which shows a list of two axes.
import matplotlib.pyplot as plt
import mpl_toolkits.axes_grid1.inset_locator as mpl_il
plt.plot()
ax2 = mpl_il.inset_axes(plt.gca(), width='60%', height='40%', loc=6)
ax2.plot()
print(plt.gcf().get_axes())
plt.show()
It's not possible to use plt.subplots() to create overlapping subplots. Also, plt.subplot2grid will not work.
However, you can create them using the figure.add_subplot() method.
import matplotlib.pyplot as plt
fig = plt.figure(1)
fig.add_subplot(111)
fig.add_subplot(222)
fig.add_subplot(223)
plt.show()