Related
I am looking to change the colour of the inner box plot generated by sns.violinplot() to black, see picture below. I've tried using patch but can only find how to do the outer edge of the violin plot and not the inner box.
Relevant code:
def poros_voilin(data):
fig, ax = plt.subplots()
sns.set_style(rc={'patch'})
ax.axhline(0.84, xmin=0.26, xmax=0.94, color='k')
ax.annotate(xy=(0.795, 0.63), xycoords='axes fraction', xytext=(0.795, 0.63), textcoords='axes fraction',
s='SGL 25 BA')
ax.axhline(0.78, xmin=0.36, xmax=0.985, color='k')
ax.annotate(xy=(0.69, 0.535), xycoords='axes fraction', xytext=(0.69, 0.535), textcoords='axes fraction',
s='Toaray 060, 090, 120')
ax.axhline(0.63, xmin=0.485, xmax=0.755, color='k')
ax.annotate(xy=(0.54, 0.29), xycoords='axes fraction', xytext=(0.54, 0.29), textcoords='axes fraction',
s='ELAT LT 1400W')
vplot = sns.violinplot(y=data['poros'].astype(float), ax=ax)
plt.show()
if __name__ == '__main__':
data = load_data()
poros_violin(data)
You can specify the color of the violin plot in the following ways.
import seaborn as sns
df = sns.load_dataset('iris')
sns.violinplot( x=df["species"], y=df["sepal_length"], color="skyblue")
import seaborn as sns
df = sns.load_dataset('iris')
sns.violinplot(x=df["species"], y=df["sepal_length"], color="skyblue", inner=None)
sns.boxenplot(x=df["species"], y=df["sepal_length"], color="red", width=0.05)
Patch artist can be used to change the colour of elements inside of a plot.
def poros_voilin(data):
fig, ax = plt.subplots()
# ax.axhline(0.84, xmin=0.26, xmax=0.98, color='k')
ax.axhline(0.84, color='k', linestyle='--', linewidth=1)
ax.annotate(xy=(0.98, 0.63), xycoords='axes fraction', xytext=(0.98, 0.63), textcoords='axes fraction',
s='SGL 25 BA', ha='right')
# ax.axhline(0.78, xmin=0.36, xmax=0.98, color='k')
ax.axhline(0.78, color='k', linestyle='-.', linewidth=1)
ax.annotate(xy=(0.98, 0.535), xycoords='axes fraction', xytext=(0.98, 0.535), textcoords='axes fraction',
s='Toray 060, 090, 120', ha='right')
# ax.axhline(0.63, xmin=0.485, xmax=0.98, color='k')
ax.axhline(0.63, color='k', linestyle=':', linewidth=1.5)
ax.annotate(xy=(0.98, 0.29), xycoords='axes fraction', xytext=(0.98, 0.29), textcoords='axes fraction',
s='ELAT LT 1400W', ha='right')
vplot = sns.violinplot(y=data['poros'].astype(float), ax=ax)
ax.get_children()[5].set_color('k') # <------------- changes the colour of the sticks
ax.get_children()[6].set_color('k') # <------------- changes the colour of the box
# sns.boxenplot(y=data['poros'].astype(float), ax=ax)
plt.show()
if __name__ == '__main__':
data = load_data()
poros_violin(data)
yields
I have tried a number of different things to fix my chart, from zorder on the plots to plt.rcParams.
I feel that this is such a simple problem but I just dont know where I have gone wrong. As you can see the bottom annotation in cyan blue is unreadable and mashed with the y label.
Ideally, the annotation sits over the y label to a point where text inside annotation is readable.
If possible just for the annotation to sit on top and still overlay the y label..something like this
Any help on this would be greatly appreciated.
ax = df.plot(x=df.columns[0], y=df.columns[1], legend=False, zorder=0, linewidth=1)
y1 =df.loc[:, df.columns[2]].tail(1)
y2= df.loc[:, df.columns[1]].tail(1)
colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
print(colors)
for var in (y1, y2):
plt.annotate('%0.2f' % var.max(), xy=(1, var.max()), zorder=1, xytext=(8, 0),
xycoords=('axes fraction', 'data'),
textcoords='offset points',
bbox=dict(boxstyle="round", fc=colors[0], ec=colors[0],))
ax2 = ax.twinx()
df.plot(x=df.columns[0], y=df.columns[2], ax=ax2, legend=False, color='#fa8174', zorder=0,linewidth=1)
ax.figure.legend(prop=subtitle_font)
ax.grid(True, color="white",alpha=0.2)
pack = [df.columns[1], df.columns[2], freq[0]]
plt.text(0.01, 0.95,'{0} v {1} - ({2})'.format(df.columns[1], df.columns[2], freq[0]),
horizontalalignment='left',
verticalalignment='center',
transform = ax.transAxes,
zorder=10,
fontproperties=subtitle_font)
ax.text(0.01,0.02,"Sources: FRED, Quandl, #Paul92s",
color="white",fontsize=10,
horizontalalignment='left',
transform = ax.transAxes,
verticalalignment='center',
zorder=20,
fontproperties=subtitle_font)
ax.xaxis.set_major_locator(matplotlib.dates.YearLocator())
ax.xaxis.set_minor_locator(matplotlib.dates.MonthLocator((4,7,10)))
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter("%Y"))
ax.xaxis.set_minor_formatter(ticker.NullFormatter()) # matplotlib.dates.DateFormatter("%m")
plt.setp(ax.get_xticklabels(), rotation=0, ha="center", zorder=-1)
plt.setp(ax2.get_yticklabels(), rotation=0, zorder=-1)
plt.setp(ax.get_yticklabels(), rotation=0, zorder=-1)
plt.gcf().set_size_inches(14,7)
ax.set_xlabel('Data as of; {0}'.format(df['Date'].max().strftime("%B %d, %Y")), fontproperties=subtitle_font)
y1 =df.loc[:, df.columns[2]].tail(1)
y2= df.loc[:, df.columns[1]].tail(1)
for var in (y1, y2):
plt.annotate('%0.2f' % var.max(), xy=(1, var.max()), zorder=1,xytext=(8, 0),
xycoords=('axes fraction', 'data'),
textcoords='offset points',
bbox=dict(boxstyle="round", fc="#fa8174", ec="#fa8174"))
plt.title('{0}'.format("FRED Velocity of M2 Money Stock v Trade Weighted U.S. Dollar Index: Broad"),fontproperties=heading_font)
ax.texts.append(ax.texts.pop())
ax.set_facecolor('#181818')
ax.figure.set_facecolor('#181818')
plt.rcParams['axes.axisbelow'] = True
I don't figure out why zorder doesn't work, but you can directly set the label style of tick labels:
import matplotlib.pyplot as plt
import numpy as np
from numpy.random import rand
import matplotlib.patches as mpatches
fig, ax = plt.subplots(1, 1)
ax.plot(rand(100), '^', color='r')
for label in ax.get_xticklabels():
label.set_bbox(dict(facecolor='orange'))
ax1 = ax.twinx()
ax1.plot(rand(100), 'o', color='b')
index_to_add_bbox = [2, 4]
ax1_labels = ax1.get_yticklabels()
for i in index_to_add_bbox:
ax1_labels[i].set_bbox(dict(boxstyle='Circle', facecolor='orange'))
plt.show()
I'm running this code to plot a graph with two-axis but I'm getting an issue to display the legend for each line plotted on for the lines for the "first axis".
#create some mark data
temp=weather.head(4)
temp.set_index('Month', inplace=True)
temp=temp.transpose()
temp_label=list(ppt.head(0))
#display(ppt)
ppt=weather.tail(1)
ppt.set_index('Month', inplace=True)
ppt=ppt.transpose()
#display(temp)
fig, ax1 = plt.subplots()
color='tab:red'
ax1.set_ylabel('Temperature', color=color)
ax1.plot(temp.index, temp.loc[:,:], label=['A','B','C','D'])
ax1.tick_params(axis='y', labelcolor=color)
leg = ax1.legend(loc='upper left', fancybox=True, shadow=True)
leg.get_frame().set_alpha(0.4)
ax2 = ax1.twinx()
color = 'tab:grey'
ax2.set_ylabel('Precipitation (mm)', color='grey')
ax2.plot(ppt.index, ppt.loc[:,:], color='grey')
ax2.tick_params(axis='y', labelcolor='grey')
leg = ax2.legend(loc='upper right', fancybox=True, shadow=False)
leg.get_frame().set_alpha(0.4)
fig.tight_layout()
plt.show()
Try:
temp.plot(ax=ax1)
instead of
ax1.plot(temp.index, temp.loc[:,:], label=['A','B','C','D'])
I have a python script that has 3 functions that plot data. 2 of them show gridlines by using ax.grid(b=True). One however, doesn't. Even after I spammed ax.grid(b=True) all over the place... I must be doing something wrong, but what?
def plotMSEProgress(times, bestScores, scores, xsplit=0, window=1):
plot, ax = plt.subplots(figsize=(20,10), num=1)
ax.grid(b=True, which='both')
# plot = plt.figure(window)
plt.ion()
plt.minorticks_on()
ax.grid(b=True, which='both')
plt.show()
plt.clf()
if xsplit:
plt.axvline(x=xsplit, color='g')
plot = plt.plot_date(times, bestScores, '-', label="best score")
plot = plt.setp(plot, color='y', linewidth=1.0)
plot = plt.plot_date(times, scores, '-', label="score")
plot = plt.setp(plot, color='b', linewidth=1.0)
ax.grid(b=True, which='both')
plt.xlabel('time')
plt.ylabel('MSE')
plt.suptitle('MSE over time', fontsize=16)
plt.legend()
ax.grid(b=True, which='both')
plt.draw()
ax.grid(b=True, which='both')
plt.pause(0.001)
ax.grid(b=True, which='both')
plt.plot()
ax.grid(b=True, which='both')
Maybe it has something to do with plt.ion() ? Because I don't have that in the othe plotting functions that do show the grid.
I already tried this and this by adding the plt.minorticks_on(), but to no avail sadly.
Is there something obvious I'm missing? Or is there some other hidden incompatibility?
Screenshot of plot as requested:
Add in a call to plt.grid() inside your function, and remove extraneous code:
import matplotlib.pyplot as plt
import datetime
def plotMSEProgress(times, bestScores, scores, xsplit=0, window=1):
plot, ax = plt.subplots(figsize=(20,10), num=1)
plt.ion()
plt.clf()
if xsplit:
plt.axvline(x=xsplit, color='g')
plot = plt.plot_date(times, bestScores, '-', label="best score")
plot = plt.setp(plot, color='y', linewidth=1.0)
plot = plt.plot_date(times, scores, '-', label="score")
plot = plt.setp(plot, color='b', linewidth=1.0)
plt.minorticks_on()
plt.grid(which='major')
plt.grid(which='minor', linestyle = ':')
plt.xlabel('time')
plt.ylabel('MSE')
plt.suptitle('MSE over time', fontsize=16)
plt.legend(loc=2)
plt.draw()
plt.pause(0.001)
# Generate example data
base = datetime.datetime.today()
times = [base + datetime.timedelta(seconds=x) for x in range(0, 100)]
scores = np.random.rand(len(times))*30
bestScores = np.random.rand(len(times))*5
# Generate plot dynamically
for i in range(len(times)):
plotMSEProgress(times[0:i], bestScores[0:i], scores[0:i], xsplit=0, window=1)
This code generates a plot and dynamically updates it, all while showing the gridlines the whole time.
I think you have some unnecessary codes, which creates multiple plots. The first plot you had is empty but with grids and the later plots contain the data, but not the grids.
Try the code below. I commented some of your scripts and made it work.
def plotMSEProgress(times, bestScores, scores, xsplit=0, window=1):
plot, ax = plt.subplots(figsize=(20,10), num=1)
ax.grid(b=True, which='both')
# plot = plt.figure(window)
plt.ion()
plt.minorticks_on()
ax.grid(b=True, which='both')
# plt.show()
# plt.clf()
if xsplit:
plt.axvline(x=xsplit, color='g')
plot = plt.plot(times, bestScores, '-', label="best score") # you can change it back to plot_date
plot = plt.setp(plot, color='y', linewidth=1.0)
plot = plt.plot(times, scores, '-', label="score") # you can change it back to plot_date
plot = plt.setp(plot, color='b', linewidth=1.0)
ax.grid(b=True, which='both')
plt.xlabel('time')
plt.ylabel('MSE')
plt.suptitle('MSE over time', fontsize=16)
plt.legend()
ax.grid(b=True, which='both')
plt.draw()
ax.grid(b=True, which='both')
plt.pause(0.001)
ax.grid(b=True, which='both')
# plt.plot()
ax.grid(b=True, which='both')
times = list(range(0,100))
bestScores = list(range(100,200))
scores = list(range(150,250))
xsplit=0
window=1
plotMSEProgress(times, bestScores, scores, xsplit=0, window=1)
I wrote the following code below to do the following graph:
fig, ax = plt.subplots(figsize=(8, 6))
ax.patch.set_facecolor('white')
ax.plot(df.index, df.X1.values, 'b',
label='NMA', linewidth=1.5)
ax.set_ylabel('Index')
ax2 = ax.twinx()
ax2.plot(df.index, df.Y.values, 'r--',
label='Rate', linewidth=1.5)
ax2.set_ylabel('Rate')
lines = ax.get_lines() + ax2.get_lines()
lgd = ax.legend(lines, [line.get_label() for line in lines],
loc='lower center', ncol=2, bbox_to_anchor=(0.5, -0.15),
frameon=False)
ax.set_title('Economic Rate and Index',
weight='bold')
for i in range(5):
plt.axvspan(Dates['Peak'][i], Dates['Trough'][i],
facecolor='grey', alpha=0.5)
plt.grid(False)
plt.savefig('C:\\test.pdf',
bbox_extra_artists=(lgd,), bbox_inches='tight')
I am having a hard time to reproduce this figure in a subplot (2X2). The only thing I would change in each of the subplots is the blue line (X1 in df... for X2, X3...). How can I have a 2X2 subplot of the above graph? Of Course I would only keep one legend at the bottom of the subplots. Thanks for the help.
The data is here and the "Dates" to reproduce the gray bars here.
This is how you could create a 2x2 raster with twinx each:
import matplotlib.pyplot as plt
fig, ((ax1a, ax2a), (ax3a, ax4a)) = plt.subplots(2, 2)
ax1b = ax1a.twinx()
ax2b = ax2a.twinx()
ax3b = ax3a.twinx()
ax4b = ax4a.twinx()
ax1a.set_ylabel('ax1a')
ax2a.set_ylabel('ax2a')
ax3a.set_ylabel('ax3a')
ax4a.set_ylabel('ax4a')
ax1b.set_ylabel('ax1b')
ax2b.set_ylabel('ax2b')
ax3b.set_ylabel('ax3b')
ax4b.set_ylabel('ax4b')
plt.tight_layout()
plt.show()
Result: