Change the colors of outline and median lines of boxplot in matplotlib - python-3.x

I am trying to create boxplot from pandas dataframe using matplotlib.
I am able to get the boxplot and change the linewidth of outlines and median lines, but I would like to change all the colors to black.
I tried several ways as described in Pandas boxplot: set color and properties for box, median, mean and Change the facecolor of boxplot in pandas.
However, none of them worked for my case.
Could someone solve these problems?
Here are my codes:
version: python 3.6.5
import pandas as pd
from pandas import DataFrame, Series
import matplotlib.pyplot as plt
df = pd.read_excel("training.xls")
fig = plt.figure()
ax = fig.add_subplot(111)
boxprops = dict(color="black",linewidth=1.5)
medianprops = dict(color="black",linewidth=1.5)
df.boxplot(column=["MEAN"],by="SrcID_Feat",ax=ax,
boxprops=boxprops,medianprops=medianprops)
plt.grid(False)
Result

I found that unless I add the argument patch_artist=True, none of the boxprops dictionaries have any effect on the boxplot. For example, when I generated a boxplot where I changed the facecolor to yellow, I had to use the following coding:
plt.boxplot(boxplot_data, positions=[1], patch_artist=True, boxprops=dict(facecolor='yellow'), showmeans=True)

Here is a way to solve your problem (details which are not relevant for the question are omitted):
fig, ax = plt.subplots()
box_plot = ax.boxplot(..., patch_artist=True)
for median in box_plot['medians']:
median.set_color('black')
median is an object of type matplotlib.lines.Line2D which exposes a method set_color which can be used to set the color of each box.

Related

How to add two consequetive colors to bars in a plotly barchart with values of one pandas column

I would like to have a barchart where two colors are used for the bars, f.i. first blue next red, than blue again followed by red.
In matplotlib this is possible see below code.
I would like to do this also with plotly express.
Suggestions are appreciated.
df_1 = pd.DataFrame(freqfinal, columns=['teller' , 'frequenties']) # df = dataframe, pd staat voor Pandas
fig = go.Figure()
fig.add_trace(go.Bar(x=df_1.teller, y=df_1.frequenties, showlegend= True))
fig.show()
# in matplotlib, it works with two colors
bar_colors = ['red', 'blue']
ax = df_1['frequenties'].plot(kind='bar', color=bar_colors, title= 'series per 100 trekkingen') # barchart met behulp van matplotlib
ax.set_xlabel('volgorde frequenties') #label x-as
ax.set_ylabel('serie grootte') # label y-as
plt.show()
See above, first part is the plotly base code second part is the matplotlib code where I was succesful to have the two colors side by side
If you give us a list of desired color combinations for the marker color, we can create the expected color scheme.
import pandas as pd
import numpy as np
np.random.seed(1)
df_1 = pd.DataFrame({'teller': list('ABCDEFGHIK'), 'frequenties': np.random.randint(0,50,10)})
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Bar(x=df_1.teller, y=df_1.frequenties, marker_color=['blue','red']*5, showlegend=True))
fig.show()

Python matplotlib custom colorbar for plotted lines with manually assigned colors

I'm trying to define a colorbar for the following type of plot.
import matplotlib.pyplot as plt
import numpy as np
for i in np.arange(0,10,0.1):
plt.plot(range(10),np.ones(10)*i,c=[i/10.,0.5,0.25])
plt.show()
This is just a simplified version of my actual data, but basically, I'd like a series of lines plotted and colored by another variable with a colorbar key. This is easy to do in scatter, but I can't get scatter to plot connected lines. Points are too clunky. I know this sounds like basic stuff, but I'm having a helluva time finding a simple solution ... what obvious solution am I missing?
You can build a custom color map and a mappable from it, then pass to colorbar:
from matplotlib.cm import ScalarMappable
from matplotlib.colors import Normalize
import matplotlib.colors as mcolors
color_list = [(i/10, 0.5,0.25) for i in np.arange(0,10,0.1)]
cmap = mcolors.LinearSegmentedColormap.from_list("my_colormap", color_list)
cmappable = ScalarMappable(norm=Normalize(0,10), cmap=cmap)
plt.figure(figsize=(10,10))
for j,i in enumerate(np.arange(0,10,0.1)):
plt.plot(range(10),np.ones(10)*i,c=color_list[j])
plt.colorbar(cmappable)
plt.show()
Output:

X and Y label being cut in matplotlib plots

I have this code:
import pandas as pd
from pandas import datetime
from pandas import DataFrame as df
import matplotlib
from pandas_datareader import data as web
import matplotlib.pyplot as plt
import datetime
start = datetime.date(2016,1,1)
end = datetime.date.today()
stock = 'fb'
fig = plt.figure(dpi=1400)
data = web.DataReader(stock, 'yahoo', start, end)
fig, ax = plt.subplots(dpi=720)
data['vol_pct'] = data['Volume'].pct_change()
data.plot(y='vol_pct', ax = plt.gca(), title = 'this is the title \n second line')
ax.set(xlabel="Date")
ax.legend(loc='upper center', bbox_to_anchor=(0.32, -0.22), shadow=True, ncol=2)
plt.savefig('Test')
This is an example of another code but the problem is the same:
At bottom of the plot you can see that the legend is being cut out. In another plot of a different code which i am working on, even the ylabel is also cut when i save the plot using plt.savefig('Test').How can i can fix this?
It's a long-standing issue with .savefig() that it doesn't check legend and axis locations before setting bounds. As a rule, I solve this with the bbox_inches argument:
plt.savefig('Test', bbox_inches='tight')
This is similar to calling plt.tight_layout(), but takes all of the relevant artists into account, whereas tight_layout will often pull some objects into frame while cutting off new ones.
I have to tell pyplot to keep it tight more than half the time, so I'm not sure why this isn't the default behavior.
plt.subplots_adjust(bottom=0.4 ......)
I think this modification will satisfy you.
Or maybe you can relocate the legend to loc="upper left"
https://matplotlib.org/api/_as_gen/matplotlib.pyplot.subplots_adjust.html
please also checked this issue which raised 8 years ago..
Moving matplotlib legend outside of the axis makes it cutoff by the figure box

How to set figure size in lmplot seaborn? [duplicate]

How do I change the size of my image so it's suitable for printing?
For example, I'd like to use to A4 paper, whose dimensions are 11.7 inches by 8.27 inches in landscape orientation.
You can also set figure size by passing dictionary to rc parameter with key 'figure.figsize' in seaborn set method:
import seaborn as sns
sns.set(rc={'figure.figsize':(11.7,8.27)})
Other alternative may be to use figure.figsize of rcParams to set figure size as below:
from matplotlib import rcParams
# figure size in inches
rcParams['figure.figsize'] = 11.7,8.27
More details can be found in matplotlib documentation
You need to create the matplotlib Figure and Axes objects ahead of time, specifying how big the figure is:
from matplotlib import pyplot
import seaborn
import mylib
a4_dims = (11.7, 8.27)
df = mylib.load_data()
fig, ax = pyplot.subplots(figsize=a4_dims)
seaborn.violinplot(ax=ax, data=df, **violin_options)
Note that if you are trying to pass to a "figure level" method in seaborn (for example lmplot, catplot / factorplot, jointplot) you can and should specify this within the arguments using height and aspect.
sns.catplot(data=df, x='xvar', y='yvar',
hue='hue_bar', height=8.27, aspect=11.7/8.27)
See https://github.com/mwaskom/seaborn/issues/488 and Plotting with seaborn using the matplotlib object-oriented interface for more details on the fact that figure level methods do not obey axes specifications.
first import matplotlib and use it to set the size of the figure
from matplotlib import pyplot as plt
import seaborn as sns
plt.figure(figsize=(15,8))
ax = sns.barplot(x="Word", y="Frequency", data=boxdata)
You can set the context to be poster or manually set fig_size.
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
np.random.seed(0)
n, p = 40, 8
d = np.random.normal(0, 2, (n, p))
d += np.log(np.arange(1, p + 1)) * -5 + 10
# plot
sns.set_style('ticks')
fig, ax = plt.subplots()
# the size of A4 paper
fig.set_size_inches(11.7, 8.27)
sns.violinplot(data=d, inner="points", ax=ax)
sns.despine()
fig.savefig('example.png')
This can be done using:
plt.figure(figsize=(15,8))
sns.kdeplot(data,shade=True)
In addition to elz answer regarding "figure level" methods that return multi-plot grid objects it is possible to set the figure height and width explicitly (that is without using aspect ratio) using the following approach:
import seaborn as sns
g = sns.catplot(data=df, x='xvar', y='yvar', hue='hue_bar')
g.fig.set_figwidth(8.27)
g.fig.set_figheight(11.7)
This shall also work.
from matplotlib import pyplot as plt
import seaborn as sns
plt.figure(figsize=(15,16))
sns.countplot(data=yourdata, ...)
For my plot (a sns factorplot) the proposed answer didn't works fine.
Thus I use
plt.gcf().set_size_inches(11.7, 8.27)
Just after the plot with seaborn (so no need to pass an ax to seaborn or to change the rc settings).
See How to change the image size for seaborn.objects for a solution with the new seaborn.objects interface from seaborn v0.12, which is not the same as seaborn axes-level or figure-level plots.
Adjusting the size of the plot depends if the plot is a figure-level plot like seaborn.displot, or an axes-level plot like seaborn.histplot. This answer applies to any figure or axes level plots.
See the the seaborn API reference
seaborn is a high-level API for matplotlib, so seaborn works with matplotlib methods
Tested in python 3.8.12, matplotlib 3.4.3, seaborn 0.11.2
Imports and Data
import seaborn as sns
import matplotlib.pyplot as plt
# load data
df = sns.load_dataset('penguins')
sns.displot
The size of a figure-level plot can be adjusted with the height and/or aspect parameters
Additionally, the dpi of the figure can be set by accessing the fig object and using .set_dpi()
p = sns.displot(data=df, x='flipper_length_mm', stat='density', height=4, aspect=1.5)
p.fig.set_dpi(100)
Without p.fig.set_dpi(100)
With p.fig.set_dpi(100)
sns.histplot
The size of an axes-level plot can be adjusted with figsize and/or dpi
# create figure and axes
fig, ax = plt.subplots(figsize=(6, 5), dpi=100)
# plot to the existing fig, by using ax=ax
p = sns.histplot(data=df, x='flipper_length_mm', stat='density', ax=ax)
Without dpi=100
With dpi=100
# Sets the figure size temporarily but has to be set again the next plot
plt.figure(figsize=(18,18))
sns.barplot(x=housing.ocean_proximity, y=housing.median_house_value)
plt.show()
Some tried out ways:
import seaborn as sns
import matplotlib.pyplot as plt
ax, fig = plt.subplots(figsize=[15,7])
sns.boxplot(x="feature1", y="feature2",data=df) # where df would be your dataframe
or
import seaborn as sns
import matplotlib.pyplot as plt
plt.figure(figsize=[15,7])
sns.boxplot(x="feature1", y="feature2",data=df) # where df would be your dataframe
The top answers by Paul H and J. Li do not work for all types of seaborn figures. For the FacetGrid type (for instance sns.lmplot()), use the size and aspect parameter.
Size changes both the height and width, maintaining the aspect ratio.
Aspect only changes the width, keeping the height constant.
You can always get your desired size by playing with these two parameters.
Credit: https://stackoverflow.com/a/28765059/3901029

Plotting Pandas into subplots

da is my dataframe. I want to make this figure into one subplot out of 2 that I will have. When I add plt.subplots(2,1,2) for this figure it ends up separating this figure into a separate figure and the subplot is an empty figure.
How can I make this code into a subplot?
-Thank you in advance, I am a newbie in python.
ax1 = da.plot(rot = 90, title ='Pre-Folsom Dam Spring Recession')
ax1.set_xlabel('Water Year Day')
ax1.axhline( y = float(fSP_Mag) , xmin=0, xmax=35,color ='r', linestyle='--',zorder=0,label= 'Magnitude')
ax1.axvline(x=float(fSP_Tim), color ='r',linestyle='--', label='Timing')
ax1.legend(framealpha=1, frameon=True)
import pandas as pd
import matplotlib.pyplot as plt
data=pd.DataFrame({"col1":[1,2,3,4,5],"col2":[2,4,6,8,10]})
fig=plt.figure()
ax1=fig.add_subplot(2,1,1)
ax2=fig.add_subplot(2,1,2)
data["col1"].plot(ax=ax1)
data["col2"].plot(ax=ax2)
Create a plt.figure() and assign subplots to ax1 and ax2.Now plot the dataframe using these axes.
Reference:-
Pyplot

Resources