How to plot matplotlib errorbars - python

I tried to plot error bar with Matplotlib like graphic attached, I can't made it, any suggestion?
import numpy as np
import matplotlib.pyplot as plt
Media = data["Media"]
Periodo = data["Periodo"]
P10th = data["P10th"]
P90th = data["P90th"]
ind = np.arange(N) # the x locations for the groups
width = 0.35 # the width of the bars: can also be len(x) sequence
fig, ax = plt.subplots()
ax.errorbar(Media, P90th, P10th, color='red', ls='--', marker='o', capsize=5, capthick=1, ecolor='black')
plt.xticks(ind, ('1910-1940', '1950-1990', '1990-2000', '2001-2010') )
ax.set_ylim(ylims)
, please can you help me.
This is my output

Here's the plot for your data:
p_10 = [.19,.62, .77, 1]
p_90 = [7.19, 6.67, 7.36, 8.25]
M = [1.16, 2.06, 2.17, 2.52]
fig = plt.figure()
x = [1, 2, 3, 4]
y = M
yerr = [p_10, # 'down' error
p_90] # 'up' error
plt.errorbar(x, y, yerr=yerr, capsize=3, fmt="r--o", ecolor = "black")

Related

bar x-tick not as same as the image

Im not sure if i use the wrong data or if there is and edit i need to do and not seeing it. It would be nice if someone could take a look at the code. The problem here is that yerr at the first bar is at x=0 and in the image the yerr is somewhere around 2.5
Does someone know what i did wrong or forgot to edit?
the end result should be:
my code:
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1)
y_raw = np.random.randn(1000).cumsum() + 15
x_raw = np.linspace(0, 24, y_raw.size)
x_pos = x_raw.reshape(-1, 100).min(axis=1)
y_avg = y_raw.reshape(-1, 100).mean(axis=1)
y_err = y_raw.reshape(-1, 100).ptp(axis=1)
bar_width = x_pos[1] - x_pos[0]
x_pred = np.linspace(0, 30)
y_max_pred = y_avg[0] + y_err[0] + 2.3 * x_pred
y_min_pred = y_avg[0] - y_err[0] + 1.2 * x_pred
barcolor, linecolor, fillcolor = 'wheat', 'salmon', 'lightblue'
fig, axes = fig, ax = plt.subplots()
axes.set_title(label="Future Projection of Attitudes", fontsize=15)
plt.xlabel('Minutes since class began', fontsize=12)
plt.ylabel('Snarkiness (snark units)', fontsize=12)
fig.set_size_inches(8, 6, forward=True)
axes.fill_between(x_pred, y_min_pred, y_max_pred ,color='lightblue')
axes.plot(x_raw, y_raw, color='salmon')
vert_bars = axes.bar(x_pos, y_avg, yerr=y_err, color='wheat', width = bar_width, edgecolor='grey',error_kw=dict(lw=1, capsize=5, capthick=1, ecolor='gray'))
axes.set(xlim=[0, 30], ylim=[0,100])
plt.show()
yerr is meant to be the difference between the mean and the min/max. Now you're using the full difference between max and min. You might divide it by 2 to get a better approximation. To obtain the exact values, you could calculate them explicitly (see code example).
Further, by default, the bars are center aligned vs their x-position. You can use align='edge' to left-align them (as x_pos is calculated as the minimum of the range the bar represents). You could also set clip_on=False in the err_kw to make sure the error bars are never clipped by the axes.
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1)
y_raw = np.random.randn(1000).cumsum() + 15
x_raw = np.linspace(0, 24, y_raw.size)
x_pos = x_raw.reshape(-1, 100).min(axis=1)
y_avg = y_raw.reshape(-1, 100).mean(axis=1)
y_min = y_raw.reshape(-1, 100).min(axis=1)
y_max = y_raw.reshape(-1, 100).max(axis=1)
bar_width = x_pos[1] - x_pos[0]
x_pred = np.linspace(0, 30)
y_max_pred = y_avg[0] + y_err[0] + 2.3 * x_pred
y_min_pred = y_avg[0] - y_err[0] + 1.2 * x_pred
barcolor, linecolor, fillcolor = 'wheat', 'salmon', 'lightblue'
fig, ax = plt.subplots(figsize=(8, 6))
ax.set_title(label="Future Projection of Attitudes", fontsize=15)
ax.set_xlabel('Minutes since class began', fontsize=12)
ax.set_ylabel('Snarkiness (snark units)', fontsize=12)
ax.fill_between(x_pred, y_min_pred, y_max_pred, color='lightblue')
ax.plot(x_raw, y_raw, color='salmon')
vert_bars = ax.bar(x_pos, y_avg, yerr=(y_avg - y_min, y_max - y_avg),
color='wheat', width=bar_width, edgecolor='grey', align='edge',
error_kw=dict(lw=1, capsize=5, capthick=1, ecolor='grey', clip_on=False))
ax.set(xlim=[0, 30], ylim=[0, 100])
plt.tight_layout()
plt.show()

Font and colour for Python matplotlib legend- superscript

Can someone help me make the R2 writing look like the rest? Especially not italics. This is my code below:
While I'm here can anyone tell me how to either
get that R2=0.97 line in red writing to indicate that's what the red line is on the graph
or
insert a red line/red dash within the legend on that line?
I've seen other ways of doing it online but the way I've formatted my legend doesn't allow for it.
plt.rcParams["font.family"] = "Cambria"
fig, ax = plt.subplots()
ax.scatter(y_test, y_predicted ,s=10,color='darkslateblue',linewidths=1)
ax.plot([y.min(), y.max()], [y.min(), y.max()], 'k-', lw=2,)
ax.set_xlabel('Actual (%)',fontsize='large')
ax.set_ylabel('Predicted (%)',fontsize='large')
y_test, y_predicted = y_test.reshape(-1,1), y_predicted.reshape(-1,1)
ax.plot(y_test, LinearRegression().fit(y_test, y_predicted).predict(y_test), color="red", lw=2)
ax.set_title('H2O REF')
handles = [mpl_patches.Rectangle((0, 0), 1, 1, fc="white", ec="white",
lw=0, alpha=0)] * 4
labels = []
labels.append("$R^2$ = {0:.2g}".format(Rsquared))
labels.append("RMSE = {0:.2g}".format(rmse))
labels.append("MAE = {0:.2g}".format(mae))
ax.legend(handles, labels, loc='best', fontsize='x-large',
fancybox=True, framealpha=0.7,
handlelength=0, handletextpad=0)
plt.show()
Thank you :)
For the first solution, a possible way to achieve it is by only typesetting ^2 in the math environment and than setting the first label text to red as described here, see code below.
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.patches as mpl_patches
x = np.linspace(0, 1)
y = x + np.random.normal(scale=0.1, size=50)
plt.rcParams["font.family"] = "Cambria"
Rsquared = 0.9
rmse = 0.8
mae = 1
fig, ax = plt.subplots()
ax.scatter(x, y)
ax.plot(x, x, c='r')
handles = [mpl_patches.Rectangle((0, 0), 1, 1, fc="white", ec="white",
lw=0, alpha=0)] * 4
labels = []
labels.append("R$^2$ = {0:.2g}".format(Rsquared))
labels.append("RMSE = {0:.2g}".format(rmse))
labels.append("MAE = {0:.2g}".format(mae))
leg = ax.legend(handles, labels, loc='best', fontsize='x-large',
fancybox=True, framealpha=0.7,
handlelength=0, handletextpad=0)
texts = leg.get_texts()
texts[0].set_color("red")
Alternatively, you can create legend entries including the red line with Line2D.
The corresponding code down below overrides handles[0].
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.patches as mpl_patches
from matplotlib.lines import Line2D
x = np.linspace(0, 1)
y = x + np.random.normal(scale=0.1, size=50)
plt.rcParams["font.family"] = "Cambria"
Rsquared = 0.9
rmse = 0.8
mae = 1
fig, ax = plt.subplots()
ax.scatter(x, y)
ax.plot(x, x, c='r')
handles = [mpl_patches.Rectangle((0, 0), 1, 1, fc="white", ec="white",
lw=0, alpha=0)] * 4
lines = []
handles[0] = Line2D([0], [0], color='red')
labels = []
labels.append("R$^2$ = {0:.2g}".format(Rsquared))
labels.append("RMSE = {0:.2g}".format(rmse))
labels.append("MAE = {0:.2g}".format(mae))
leg = ax.legend(handles, labels, loc='best', fontsize='x-large',
fancybox=True, framealpha=0.7)

How to add error values next to error bars?

I'm using matplotlib for my plots. I have with me the plot and errorbar. I want to specify the error value in text next to the errorbars. I'm looking for something like this (edited in pinta):
Is this possible to do in this code:
import numpy as np
import matplotlib.pyplot as plt
import math
N = 8
y1 = [0.1532, 0.1861, 0.2618, 0.0584, 0.1839, 0.2049, 0.009, 0.2077]
y1err = []
for item in y1:
err = 1.96*(math.sqrt(item*(1-item)/10000))
y1err.append(err)
ind = np.arange(N)
width = 0.35
fig, ax = plt.subplots()
ax.bar(ind, y1, width, yerr=y1err, capsize=7)
ax.grid()
plt.show()
You can use the annotate function to add text labels in the plot. Here is how you could do it:
import numpy as np
import matplotlib.pyplot as plt
import math
N = 8
y1 = [0.1532, 0.1861, 0.2618, 0.0584, 0.1839, 0.2049, 0.009, 0.2077]
y1err = []
for item in y1:
err = 1.96*(math.sqrt(item*(1-item)/10000))
y1err.append(err)
ind = np.arange(N)
width = 0.35
fig, ax = plt.subplots()
ax.bar(ind, y1, width, yerr=y1err, capsize=7)
# add error values
for k, x in enumerate(ind):
y = y1[k] + y1err[k]
r = y1err[k] / y1[k] * 100
ax.annotate(f'{y1[k]:.2f} +/- {r:.2f}%', (x, y), textcoords='offset points',
xytext=(0, 3), ha='center', va='bottom', fontsize='x-small')
ax.grid()
plt.show()

matplotlib remove the ticks (axis) from the colorbar

I want to remove the (ticks) axis with numbers to the right of the colorbar. I am using matplotlib with python as follows:
f = plt.figure()
ax = f.add_subplot(1,1,1)
i = ax.imshow(mat, cmap= 'gray')
cbar = f.colorbar(i)
If you just want to remove the ticks but keep the ticklabels, you can set the size of the ticks to be 0 as following
f = plt.figure()
ax = f.add_subplot(1,1,1)
mat = np.arange(100).reshape((10, 10))
i = ax.imshow(mat, cmap= 'viridis')
cbar = f.colorbar(i)
cbar.ax.tick_params(size=0)
If you want to remove both, the ticks and the labels, you can use set_ticks([]) by passing an empty list.
cbar.set_ticks([])
Another option is to provided a formatter or locator. Here two combinations of:
a formatter which sets any value to an empty sting ('')
a locator that doesn't place a tick.
See the official matplotlib docs for more formatters or locators.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker
from mpl_toolkits.axes_grid1 import make_axes_locatable
fig, ax = plt.subplots(ncols=1)
mat = np.arange(100).reshape((10, 10))
cs = ax.imshow(mat, cmap= 'viridis')
divider = make_axes_locatable(ax)
dvider_kwargs = dict(position="right", size="15%", pad=0.5)
fig.colorbar(cs,
cax=divider.append_axes(**dvider_kwargs),
format = matplotlib.ticker.FuncFormatter(lambda x, pos: ''),
ticks = matplotlib.ticker.FixedLocator([]))
fig.colorbar(cs,
cax=divider.append_axes(**dvider_kwargs),
format = matplotlib.ticker.FuncFormatter(lambda x, pos: ''))
fig.colorbar(cs,
cax=divider.append_axes(**dvider_kwargs))
plt.tight_layout()
With make_axes_locatable and cax=divider.append_axes the colorbars have all the same size.
Another example
# gen data
n = 100000
bins = np.arange(-10, 10, .1)
value = np.random.normal(loc=20.0, scale=10.0, size=n)
samples0 = np.random.multivariate_normal([-2, 0], [[1, 0], [0, 1]], n)
samples1 = np.random.multivariate_normal([4, 4], [[1, -.9], [-.9, 1]], n)
samples2 = np.random.multivariate_normal([4, -4], [[1, .6], [.6, 1]], n)
h0, e = np.histogramdd(samples0, bins=[bins, bins], density=True)
h1, e = np.histogramdd(samples1, bins=[bins, bins], density=True)
h2, e = np.histogramdd(samples2, bins=[bins, bins], density=True)
# create figure
fig, ax = plt.subplots(ncols=1, figsize=(3,2))
kwargs = dict(vmin=0, vmax=.3)
cs0 = plt.pcolormesh(e[0][:-1], e[1][:-1], np.ma.masked_equal(h0, 0), cmap='Blues', **kwargs)
cs1 = plt.pcolormesh(e[0][:-1], e[1][:-1], np.ma.masked_equal(h1, 0), cmap='Greens', **kwargs)
cs2 = plt.pcolormesh(e[0][:-1], e[1][:-1], np.ma.masked_equal(h2, 0), cmap='Reds', **kwargs)
# create colorbars
divider = make_axes_locatable(ax)
divider_kwargs = dict(position="right", size="5%", pad=0.1)
fig.colorbar(cs0, extend='max',
cax=divider.append_axes(**divider_kwargs),
format = matplotlib.ticker.FuncFormatter(lambda x, pos: ''))
fig.colorbar(cs1, extend='max',
cax=divider.append_axes(**divider_kwargs),
format = matplotlib.ticker.FuncFormatter(lambda x, pos: ''))
fig.colorbar(cs2, extend='max',
cax=divider.append_axes(**divider_kwargs),
label='PDF')
# tune plot
ax.set_aspect('equal')
# ax.grid()
plt.tight_layout()

How to show Cartesian system in polar plot in python?

Here I tried to add the polar plot on top of the Cartesian grid,but what I got instead was 2 separate figures(one polar another Cartesian),I want this polar figure to be embedded in the Cartesian plot. Also I have used some of the code previously available as I am new to matplotlib.
from pylab import *
import matplotlib.pyplot as plt
x = [0,10,-3,-10]
y = [0,10,1,-10]
color=['w','w','w','w']
fig = plt.figure()
ax1 = fig.add_subplot(111)
scatter(x,y, s=100 ,marker='.', c=color,edgecolor='w')
circle1=plt.Circle((0,0),5,color='r',fill=False)
circle_min=plt.Circle((0,0),4.5,color='g',fill=False)
circle_max=plt.Circle((0,0),5.445,color='b',fill=False)
fig = plt.gcf()
fig.gca().add_artist(circle1)
fig.gca().add_artist(circle_min)
fig.gca().add_artist(circle_max)
left,right = ax1.get_xlim()
low,high = ax1.get_ylim()
arrow( left, 0, right -left, 0, length_includes_head = True, head_width = 0.15 )
arrow( 0, low, 0, high-low, length_includes_head = True, head_width = 0.15 )
grid()
fig = plt.figure()
ax2 = fig.add_subplot(111)
scatter(x,y, s=100 ,marker='.', c=color,edgecolor='w')
circle2=plt.Circle((0,0),5,color='r',fill=False)
circle_min=plt.Circle((0,0),4.5,color='g',fill=False)
circle_max=plt.Circle((0,0),5.445,color='b',fill=False)
fig = plt.gcf()
fig.gca().add_artist(circle2)
fig.gca().add_artist(circle_min)
fig.gca().add_artist(circle_max)
left,right = ax2.get_xlim()
low,high = ax2.get_ylim()
arrow( left, 0, right -left, 0, length_includes_head = True, head_width = 0.15 )
arrow( 0, low, 0, high-low, length_includes_head = True, head_width = 0.15 )
import numpy as np
import matplotlib.pyplot as plt
theta = np.linspace(-np.pi, np.pi, 100)
r1 = 1 - np.sin(3*theta)
r2 = 1 + np.cos(theta)
ax = plt.subplot(111, polar=True, # add subplot in polar coordinates
axisbg='Azure') # background colour
ax.set_rmax(2.2) # r maximum value
ax.grid(True) # add the grid
ax.plot(theta, r1,
color='Tomato', # line colour
ls='--', # line style
lw=3, # line width
label='a 3-fold curve') # label
ax.plot(theta, r2,
color='purple',
linewidth=3,
ls = '-',
label = 'a cardioid')
ax.legend(loc="lower right") # legend location
titlefont = {
'family' : 'serif',
'color' : 'black',
'weight' : 'bold',
'size' : 16,
}
ax.set_title("A plot in polar coordinates", # title
va='bottom', # some space below the title
fontdict = titlefont # set the font properties
)
grid()
show()
#I am getting a separate Cartesian image + a polar image while what I need is both the things in a single image
import matplotlib.pyplot as plt
import numpy as np
#########################################
color=['w','w','w','w']
theta = np.linspace(-np.pi, np.pi, 100)
fig = plt.figure()# initializing the figure
rect = [0.1, 0.1, 0.8, 0.8]# setting the axis limits in [left, bottom, width, height]
ax_carthesian = fig.add_axes(rect)# the carthesian axis:
ax_polar = fig.add_axes(rect, polar=True, frameon=False)# the polar axis:
#########################################
ax_carthesian.add_artist(plt.Circle((0.5,0.5),5/15,color='r',fill=False))
ax_carthesian.add_artist(plt.Circle((0.5,0.5),4.5/15,color='g',fill=False))
ax_carthesian.add_artist(plt.Circle((0.5,0.5),5.445/15,color='b',fill=False))
ax_polar.plot(theta, 1 - np.sin(3*theta), color='Tomato',ls='--',lw=1, label='a 3-fold curve')
ax_polar.plot(theta, 1 + np.cos(theta), color='purple',linewidth=1,ls = '-',label = 'a cardioid')
plt.show()
I am not used to matplotlib but I reduced your code to his minimum to better understand it and make it look less redudant. look at what I get:
import pylab
import matplotlib.pyplot as plt
import numpy as np
#########################################
x = [0,10,-3,-10]
y = [0,10,1,-10]
color=['w','w','w','w']
theta = np.linspace(-np.pi, np.pi, 100)
#########################################
pylab.scatter(x,y, s=100 ,marker='.', c=color,edgecolor='w')
plt.gcf().gca().add_artist(plt.Circle((0,0),5,color='r',fill=False))
plt.gcf().gca().add_artist(plt.Circle((0,0),4.5,color='g',fill=False))
plt.gcf().gca().add_artist(plt.Circle((0,0),5.445,color='b',fill=False))
plt.figure().add_subplot(111)
ax = plt.subplot(111, polar=True,axisbg='Azure')
ax.plot(theta, 1 - np.sin(3*theta),color='Tomato',ls='--',lw=3,label='a 3-fold curve')
ax.plot(theta, 1 + np.cos(theta),color='purple',linewidth=3,ls = '-',label = 'a cardioid')
pylab.show()
it is nearly the same result...

Categories