I am trying to get rid of these purple points on the picture below. Here is my code:
p_values = [0., 0.05, 0.25, 0.5, 1, 1.5, 2, 5, 10, np.inf]
xx, yy = np.meshgrid(np.linspace(-3, 3, num = 101),
np.linspace(-3, 3, num = 101))
fig, axes = plt.subplots(ncols = (len(p_values) + 1) // 2,
nrows = 2, figsize = (16, 7))
for p, ax in zip(p_values, axes.flat):
### BEGIN Solution (do not delete this comment)
z = np.linalg.norm([xx, yy], ord = p, axis = 0)
ax.contourf(yy, xx, z, 25, cmap = 'coolwarm')
ax.contour(yy, xx, z, [1], colors = 'fuchsia', linewidths = 3)
ax.set_title(f'p = {p}')
ax.legend([f'$x: |x|_{{{p}}} = 1$']);
### END Solution (do not delete this comment)
plt.show()
Which parameters should be specified in ax.legend() in order to plot the graph clear.
You could create the legend using an explicit handle. In this case the fuchsia colored line is stored as the last element of ax.collections. Creating the legend with only labels, when there were no "handles with labels" set, could be the cause of the weird purple dots.
import matplotlib.pyplot as plt
import numpy as np
p_values = [0., 0.05, 0.25, 0.5, 1, 1.5, 2, 5, 10, np.inf]
xx, yy = np.meshgrid(np.linspace(-3, 3, num=101),
np.linspace(-3, 3, num=101))
fig, axes = plt.subplots(ncols=(len(p_values) + 1) // 2,
nrows=2, figsize=(16, 7))
cmap = plt.get_cmap('magma').copy()
cmap.set_extremes(over='green', under='black', bad='turquoise')
for p, ax in zip(p_values, axes.flat):
### BEGIN Solution (do not delete this comment)
z = np.linalg.norm([xx, yy], ord=p, axis=0)
cnt = ax.contourf(yy, xx, z, 25, cmap='coolwarm')
ax.contour(yy, xx, z, [1], colors='fuchsia', linewidths=3)
ax.set_title(f'p = {p}')
ax.legend(handles=[ax.collections[-1]], labels=[f'$x: |x|_{{{p}}} = 1$'])
plt.colorbar(cnt, ax=ax)
### END Solution (do not delete this comment)
plt.tight_layout()
plt.show()
Related
I'm trying to have the following plot to appear like the second plot.
Without the axises (vertical, horizontal) that have no meaning for this plot and range from 0 to 1.
This is the code I'm using to generate to plot:
import matplotlib.pyplot as plt
import numpy as np
x_lim = (0, 1)
y_lim = (0, 1)
z_lim = (0, 1)
list_points = [[0.3, 0.3, 0], [0.4, 0.4, 0], [0, 0, 0], [.1, .1, .5], [0.3, 0.3, .2]]
def plot_tracking_map():
"""
Visualize all grapes centers on a 3d map.
This function generates a plot that represents the TB in 3D.
"""
x_cors, y_cors, z_cors = [], [], []
for i in range(len(list_points)):
x_cor, y_cor, z_cor = list_points[i][0], list_points[i][1], list_points[i][2]
x_cors.append(x_cor)
y_cors.append(y_cor)
z_cors.append(z_cor)
fig, ax = plt.subplots(figsize=(12, 12))
ax = fig.add_subplot(projection='3d')
yy, zz = np.meshgrid(range(2), range(2))
xx = yy
s = ax.scatter(x_cors, y_cors, z_cors, s=400, marker='o') # x,y,z coordinates, size of each point, colors.
# controls the alpha channel. all points have the same value, ignoring their distance
s.set_edgecolors = s.set_facecolors = lambda *args: None
ax.title.set_text(f'Imgae number 1')
plt.show()
plot_tracking_map()
edit
I changed the lines
fig, ax = plt.subplots(figsize=(12, 12))
ax = fig.add_subplot(projection='3d')
to
fig, ax = plt.subplots(figsize=(12, 12), subplot_kw={'projection': '3d'})
And it solved the problem.
I have the following code generating a bar graph. However, for the last bar, I need a star marker to show that there is no data for the last bar, here in the graph it's number 10.
data = pd.read_csv('data.csv')
df = pd.DataFrame(data)
plt.figure(figsize=(3,2))
X = list(df.iloc[:, 0])
Y = list(df.iloc[:, 1])
Z= list(df.iloc[:, 2])
X_axis = np.arange(len(X))
plt.bar(X_axis - 0.2, Y, 0.4, label='Actual',color='#436bad')
plt.bar(X_axis + 0.2, Z, 0.4, label='Predicted',color='#c5c9c7')
plt.legend(loc=2, prop={'size': 6.5})
labels=['1','2','3','4','5','6','7','8','9','10']
plt.xticks(X,labels,rotation=60)
plt.xlabel("Node no")
plt.ylabel("Accuracy (%)")
plt.ylim(60,95)
You can use plt.text and set * where do you want, like below:
(Because I can't run your code. I send an example)
import matplotlib.pyplot as plt
import numpy as np
x = np.array([1,3,7])
y = [2, 3, 2]
z = [1, 2, 3]
plt.bar(x-0.1, y, width=0.2, color='b', align='center')
plt.bar(x+0.1, z, width=0.2, color='g', align='center')
labels=[1,2,3,4,5,6,7,8,9,10]
plt.xticks(range(1,11),labels,rotation=60)
str_x = [l for l in labels if not l in x]
for s_x in str_x:
plt.text(s_x, 0.1, '*', ha='center', fontsize=26)
Output:
Here is a part of the plot that I have
I need to create TrendLine that would be extended to the 3th
quarter of this plot... I can's think of any solution.
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
x = [1, 8, 12, 20]
y = [1, 8.4, 12.5, 20]
fig = plt.figure(figsize=(20,20))
ax = fig.add_subplot()
ax.set_xlim(-30, 30)
ax.set_ylim(-20, 20)
plt.subplot().spines['left'].set_position('center')
plt.subplot().spines['bottom'].set_position('center')
plt.plot(x,y, 'b.', ms=20)
plt.minorticks_on()
ax.grid(True, which='both')
mean_line = ax.plot()
z = np.polyfit(x, y, 1)
p = np.poly1d(z)
plt.plot(x,p(x),"r--")
plt.show()
I don't think reverse x and y would do the job, it would be limited to the poly1d that pass (0,0)
I think the extending method should be using the fitted line itself.
so a more general method is extend the x and use the poly1d(z) to calculate an extended line. z is description of the fitted line, so feeding x value to z would draw the line.
import matplotlib.pyplot as plt
import numpy as np
import warnings
warnings.filterwarnings('ignore')
x = [1, 8, 12, 20]
y = [1, 8.4, 12.5, 20]
# make an xx that with from -20 to 20
#xx =np.array(x)
#xx = sorted(np.concatenate((-xx, xx), axis=0))
xx = [-20, 20] # also work
fig, ax = plt.subplots(figsize=(10,10))
ax.set_xlim(-30, 30)
ax.set_ylim(-20, 20)
plt.subplot().spines['left'].set_position('center')
plt.subplot().spines['bottom'].set_position('center')
plt.subplot().spines['right'].set_color('none')
plt.subplot().spines['top'].set_color('none')
plt.plot(x,y, 'b.', ms=20)
plt.minorticks_on()
#ax.grid(True, which='both')
plt.subplot().grid(True, which='both')
mean_line = ax.plot()
z = np.polyfit(x, y, 1)
p = np.poly1d(z)
plt.plot(xx,p(xx),"r--")
plt.show()
if you zoomin near the (0,0), you should see it's not passing the origin point.
zoomed in near (0,0)
result image
I don't have any experience with trendlines, but I created a composite of existing x and y values with different signs and drew the following graph.
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings('ignore')
x = [1, 8, 12, 20]
y = [1, 8.4, 12.5, 20]
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot()
ax.set_xlim(-30, 30)
ax.set_ylim(-20, 20)
plt.subplot().spines['left'].set_position('center')
plt.subplot().spines['bottom'].set_position('center')
plt.plot(x,y, 'b.', ms=20)
plt.minorticks_on()
ax.grid(True, which='both')
mean_line = ax.plot()
# update
xx =np.array(x)
xx = sorted(np.concatenate((-xx, xx), axis=0))
yy =np.array(y)
yy = sorted(np.concatenate((-yy, yy), axis=0))
z = np.polyfit(xx, yy, 1)
p = np.poly1d(z)
plt.plot(xx,p(xx),"r--")
plt.show()
I am trying to draw two data lines with error bars, each having the same color as the data line. However, I get another thin line with a color I have not specified in each data line when I add an error bar.
Also, I would like to make the caps of the error bars thicker but the option capthick is not valid here.
Could anybody please help me fix these issues?
This is my code.
import matplotlib.pyplot as plt
from pylab import *
import numpy as np
xaxis = [1, 2, 3]
mean1 = [1,2,3.6]
se1 = [0.2, 0.5, 0.9]
mean2 = [10, 29, 14]
se2 = [3, 4, 2]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlabel('X', fontsize = 16)
ax.set_ylabel('Y', fontsize = 16)
ax.axis([0, 5, 0, 35])
ax.plot(xaxis, mean1, 'r--', linewidth = 4)
ax.errorbar(xaxis, mean1, yerr = se1, ecolor = 'r', elinewidth = 2, capsize = 5)
ax.plot(xaxis, mean2, 'b--', linewidth = 4)
ax.errorbar(xaxis, mean2, yerr = se2, ecolor = 'b', elinewidth = 2, capsize = 5)
plt.show()
The extra thin line is coming from the errorbar() call.
errorbar will draw a line too, what you're doing is changing the colour of the error bars, but not the actual lines (hence it using the standard matplotlib first two colours, blue and green.
it's all in the documentaion, here.
To achieve what you want, you only need to use the errorbar() function;
This does what you want i think, maybe jsut tweak the numbers a bit.
import matplotlib.pyplot as plt
from pylab import *
import numpy as np
xaxis = [1, 2, 3]
mean1 = [1,2,3.6]
se1 = [0.2, 0.5, 0.9]
mean2 = [10, 29, 14]
se2 = [3, 4, 2]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlabel('X', fontsize = 16)
ax.set_ylabel('Y', fontsize = 16)
ax.axis([0, 5, 0, 35])
linestyle = {"linestyle":"--", "linewidth":4, "markeredgewidth":5, "elinewidth":5, "capsize":10}
ax.errorbar(xaxis, mean1, yerr = se1, color="r", **linestyle)
ax.errorbar(xaxis, mean2, yerr = se2, color="b", **linestyle)
plt.show()
I put the common line style arguments into a dict which gets unpacked.
I have to plot contour and wireframe plots for function . This is the code I have so far:
# Number of uniformly ditributed random numbers
n = 2000
def func_vec(x1s, x2s):
return x1s * x1s + 4 * x2s * x2s
np.random.seed()
x1s = np.random.uniform(-1, 1, n)
x2s = np.random.uniform(-1, 1, n)
ys = func_vec(x1s, x2s)
fig = plt.figure()
# Scatter
ax1 = fig.add_subplot(1, 2, 1)
ax1.scatter(x1s, x2s, color = 'g', s = 2, edgecolor = 'none')
ax1.set_ylim([-1,1])
ax1.set_xlim([-1,1])
# Contour
ax1.contour(x2s, x1s, ys[np.newaxis,:].repeat(n, axis = 0))
# 3D visualization
ax2 = fig.add_subplot(1, 2, 2, projection = '3d')
X = x1s
Y = x2s
Z = ys
ax2.plot_wireframe(X, Y, Z, rstride = 1, cstride = 1)
plt.show()
What I don't understand is how do contour() and plot_firewrame() actually work? Can somebody please be so kind and explain this to me (in the context of specified function)? Furthermore, how should I specify X, Y and Z?
This is how the plot looks now:
and this is how it should look like (scatter above works OK):
Here's the code that will produce the correct plots. Anyone struggling with this, should find the code pretty much self-explanatory:
# Number of uniformly ditributed random numbers
n = 2000
def func_vec(x1s, x2s):
return x1s * x1s + 4 * x2s * x2s
np.random.seed()
x1s = np.random.uniform(-1, 1, n)
x2s = np.random.uniform(-1, 1, n)
ys = func_vec(x1s, x2s)
fig = plt.figure(22)
# Scatter
ax1 = fig.add_subplot(1, 2, 1)
ax1.scatter(x1s, x2s, color = 'g', s = 2, edgecolor = 'none')
ax1.set_ylim([-1,1])
ax1.set_xlim([-1,1])
# Contour
xi = np.linspace(-1,1,20)
yi = np.linspace(-1,1,20)
zi = griddata((x2s, x1s), ys, (xi[None,:], yi[:,None]), method = 'cubic')
ax1.contour(xi, yi, zi, 6, linewidths = 1, colors = ('#0000ff', '#0099ff', '#009999', '#999900', '#ff9900', '#ff0000'))
# 3D visualization
ax2 = fig.add_subplot(1, 2, 2, projection = '3d')
X, Y = np.meshgrid(xi, yi)
ax2.plot_wireframe(X, Y, zi, rstride = 1, cstride = 1)
ax2.view_init(28, -144)
plt.show()