from this code,
import matplotlib.pyplot as plt
import numpy as np
def f(x):
return x*x*np.sqrt(x+1)
# prepare coordinate vectors
x = np.linspace(-1, 1.5, 500)
y = f(x)
# create figure and axes
fig, ax = plt.subplots(1,1)
# format spines
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.spines['left'].set_position(('data', 0))
ax.spines['bottom'].set_position(('data', 0))
# plot and format
ax.plot(x,y, 'r-')
ax.plot([-1, -4/5, 0], [f(-1), f(-4/5), f(0)], linestyle="", marker='o', mfc='b', mec='r')
ax.set_xlabel(r'$x$'); ax.set_title(r'$y = x^2\sqrt{x+1}$')
ax.set_xlim([-1.5,1.5])
ax.annotate('local max', xy=(-4/5-0.05, f(-4/5)+0.1), xycoords='data', xytext=(-1.2, 1.5),
ha='right', va='top', arrowprops={'fc':'blue',}
)
# save the figure
fig.savefig('sketch.png')
plt.show()
What is the '$' sign mean in python?
thank you.I was trying to search on internet but cannot really understand it,thank you.
The $ doesn't mean anything in Python - it's just that character in a string. Matplotlib uses it for rendering LaTeX: https://matplotlib.org/stable/tutorials/text/usetex.html
Related
When I run the following lines, I get a plot with a large space at the top and the bottom with no bars.
How can I remove this extra space?
import pandas as pd
import numpy as np
import random
import matplotlib.pyplot as plt
from matplotlib.transforms import Affine2D
random.seed(1)
df = pd.DataFrame(np.random.randn(50, 1), columns=["parameter"])
df["standard_error"]= ((df.parameter**2)**0.5)/2
name = "plot"
x = ["A"+str(x) for x in df.index.tolist()]
y1 = df.parameter
yerr1 = df.standard_error
fig, ax = plt.subplots()
fig.set_figheight(len(x))
plt.rc('axes', labelsize=22)
plt.grid(b=True, which='major', color='#666666', linestyle='-', alpha=0.2)
trans1 = Affine2D().translate(-0.1, 0.0) + ax.transData
trans2 = Affine2D().translate(+0.1, 0.0) + ax.transData
er1 = ax.errorbar(y1, x, xerr=yerr1, marker="o", linestyle="none", transform=trans1)
ax.axvline(x=0, color="black")
plt.savefig(name + '.png', bbox_inches='tight')
If you mean the extra space below and above your smallest and largest data points along the y-axis then you can simply use plt.ylim, e.g:
plt.ylim(0, 50)
Which will change the extent of the y-axis to the range 0 - 50. Similarly for the x-axis there's plt.xlim
I have a main plot and I'm trying to include a detail of a zoomed part in the same plot.
Most of my tries end with the error:
Can not reset the axes. You are probably trying to re-use an artist in more than one Axes which is not supported.
I've seen examples that work but none of them have an iteration for the subplot. Can somebody help me with this issue?
My code is very similar to this:
import matplotlib.pyplot as plt
import numpy.random as rnd
from matplotlib.patches import Ellipse
NUM = 250
ells = [Ellipse(xy=rnd.rand(2)*10, width=rnd.rand(), height=rnd.rand(), angle=rnd.rand()*360)
for i in range(NUM)]
fig = plt.figure(0)
ax = fig.add_subplot(111, aspect='equal')
for e in ells:
ax.add_artist(e)
e.set_clip_box(ax.bbox)
e.set_alpha(rnd.rand())
e.set_facecolor(rnd.rand(3))
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
#Subfigure
ax2 = plt.axes([.5, .3, .2, .2])
#I have to iterate in a subset of ells
plt.xticks([])
plt.yticks([])
plt.setp(ax2, xticks=[], yticks=[])
plt.show()
I have the following code :
def plot_diff_dist(ax, simulations, real_difference, bins=20):
p=pvalue(simulations, real_difference)
ax.hist(simulations, bins=bins )
ax.axvline(real_difference, color='r', linewidth=5)
later plot_diff_dist will be called with other functions that plots histogram on different axes, i need to add p as a legend to every histogram it produces. so i need to change this function to attach p as a legend to every histogram.
Suppose you have some code to produce a histogram like this
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(0)
x = np.random.poisson(3, size=100)
p = 5.
plt.hist(x, bins=range(10))
l = plt.axvline(p, color="crimson")
legend
You can use a legend and provide your axvline as legend handler, as well as the formatted value as legend text.
plt.legend([l], ["p={}".format(p)], loc=1)
text
You can use text to place a text in the figure. By default, the coordinates are data coordinates, but you can specify a transform to switch e.g. to axes coordinates.
plt.text(.96,.94,"p={}".format(p), bbox={'facecolor':'w','pad':5},
ha="right", va="top", transform=plt.gca().transAxes )
annotate
You can use annotate to produce a text somewhere in the figure. The advantage compared to text is that you may (a) use an additional arrow to point to an object, and (b) that you may specify the coordinate system in terms of a simple string, instead of a transform.
plt.annotate("p={}".format(p), xy=(p, 15), xytext=(.96,.94),
xycoords="data", textcoords="axes fraction",
bbox={'facecolor':'w','pad':5}, ha="right", va="top",
arrowprops=dict(facecolor='black', shrink=0.05, width=1))
AnchoredText
You can use an AnchoredText from offsetbox:
from matplotlib.offsetbox import AnchoredText
a = AnchoredText("d={}".format(d), loc=1, pad=0.4, borderpad=0.5)
plt.gca().add_artist(a)
You might try this solution from SO post.
from matplotlib.patches import Rectangle
df = pd.DataFrame({'x':np.random.normal(2500,size=1000)})
ax = df.plot.hist()
ax.axvline(2501,color='r', linewidth=2)
extra = Rectangle((0, 0), 100, 100, fc="w", fill=False, edgecolor='none', linewidth=0)
ax.legend([extra],('p = 1.2',"x")).2',"x"))
Edit: Show P as a variable:
from matplotlib.patches import Rectangle
df = pd.DataFrame({'x':np.random.normal(2500,size=1000)})
ax = df.plot.hist()
p=1.2
ax.axvline(2501,color='r', linewidth=2)
extra = Rectangle((0, 0), 100, 100, fc="w", fill=False, edgecolor='none', linewidth=0)
ax.legend([extra],('p = {}'.format(p),"x"))
I would like to update the arrow position while in a loop of plots. I found this post that has an analogous question for the situation in which the patch is a rectangle. Below, the solution proposed in the mentioned post with the addition of the Arrow patch.
from matplotlib import pyplot as plt
from matplotlib.patches import Rectangle, Arrow
import numpy as np
nmax = 10
xdata = range(nmax)
ydata = np.random.random(nmax)
fig, ax = plt.subplots()
ax.plot(xdata, ydata, 'o-')
ax.xaxis.set_ticks(xdata)
plt.ion()
rect = plt.Rectangle((0, 0), nmax, 1, zorder=10)
ax.add_patch(rect)
arrow = Arrow(0,0,1,1)
ax.add_patch(arrow)
for i in range(nmax):
rect.set_x(i)
rect.set_width(nmax - i)
#arrow.what --> which method?
fig.canvas.draw()
plt.pause(0.1)
The problem with the Arrow patch is that apparently it does not have a set method related with its position as the Rectangle patch has. Any tip is welcome.
The matplotlib.patches.Arrow indeed does not have a method to update its position. While it would be possible to change its transform dynamically, I guess the easiest solution is to simply remove it and add a new Arrow in each step of the animation.
from matplotlib import pyplot as plt
from matplotlib.patches import Rectangle, Arrow
import numpy as np
nmax = 9
xdata = range(nmax)
ydata = np.random.random(nmax)
plt.ion()
fig, ax = plt.subplots()
ax.set_aspect("equal")
ax.plot(xdata, ydata, 'o-')
ax.set_xlim(-1,10)
ax.set_ylim(-1,4)
rect = Rectangle((0, 0), nmax, 1, zorder=10)
ax.add_patch(rect)
x0, y0 = 5, 3
arrow = Arrow(1,1,x0-1,y0-1, color="#aa0088")
a = ax.add_patch(arrow)
plt.draw()
for i in range(nmax):
rect.set_x(i)
rect.set_width(nmax - i)
a.remove()
arrow = Arrow(1+i,1,x0-i+1,y0-1, color="#aa0088")
a = ax.add_patch(arrow)
fig.canvas.draw_idle()
plt.pause(0.4)
plt.waitforbuttonpress()
plt.show()
I'm trying to plot a polar plot with this code:
import numpy as np
import matplotlib.pylab as plt
def power(angle, l, lam):
return 1/(lam) * ((np.cos(np.pi*l*np.cos(angle)/lam) - np.cos(np.pi*l/lam))/np.sin(angle))**2
fig = plt.figure(1)
ax = fig.add_subplot(111, projection='polar')
theta = np.linspace(0.001, 2*np.pi, 100)
P1 = power(theta, 1, 5)
ax.plot(theta, P1, color='r', linewidth=3)
plt.savefig('1.png')
and I get this plot:
I would like to change 2 things. The first and more important one is to hide the radial tick labels (I just want to show the general form of the plot).
If possible, how can I choose the vertical axis to correspond to 0°?
Thanks for your help.
You can use set_yticklabels() to remove the radial ticks and set_theta_zero_location() to change the zero location:
fig = plt.figure(1)
ax = fig.add_subplot(111, projection='polar')
ax.plot(theta, P1, color='r', linewidth=3)
ax.set_yticklabels([])
ax.set_theta_zero_location('N')
plt.show()
You might also want to change the direction of the azimuthal axis:
ax.set_theta_direction(-1)
You can set the theta zero position with ax.set_theta_zero_location('N').
To modify the r tick labels, you could do something like
for r_label in ax.get_yticklabels():
r_label.set_text('')
If you want to remove them entirely, do ax.set_yticklabels([]).
More methods can be found in the PolarAxes documentation.