secondary Y axis position matplotlib - matplotlib

I need to change the secondary Y axis position on a matplotlib plot.
It's like a subplot inside the same plot.
In the image below, my secondary Y axis starts at the same position as first y axis. I need that the secondary Y axis starts about at the "18" position of the first Y axis, with a smaller scale (red line).

If I understand the question, you want a twinx axis, as #kikocorreoso says, but you also want to compress it, so it only takes up the upper portion of the y axis.
You can do this by just setting the ylim larger than you need it, and explicitly setting the yticks. Here's an example with some random data
import matplotlib.pyplot as plt
import numpy as np
data = [np.random.normal(np.random.randint(0,5),4,25) for _ in range(25)] # some random data
fig=plt.figure()
ax1=fig.add_subplot(111)
ax2=ax1.twinx()
ax1.set_ylim(-5,25)
ax2.set_ylim(0,14)
ax2.set_yticks([10,12,14]) # ticks below 10 don't show up
ax1.boxplot(data)
ax2.plot(np.linspace(0,26,50),12.+2.*np.sin(np.linspace(0,2.*np.pi,50))) # just a random line
plt.show()

If I understood correctly seeing the figure you posted you want a second y-axis. You can do this using plt.twinx. An example could be like the following:
import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.twinx()
plt.plot([5,4,5])
plt.show()

Related

Data visualization using Matplotlib

By using this code I'm able to generate 20 data points on y-axis corresponding to x-axis, but I want to mark the 25 data points on the line as downward pointed triangles without changing arr_x=np.linspace(0.0,5.0,20) to arr_x=np.linspace(0.0,5.0,25).
will it possible to mark additional data points on y-axis without changing x-axis ?
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
def multi_curve_plot():
# Write your functionality below
fig=plt.figure(figsize=(13,4))
ax=fig.add_subplot(111)
arr_x=np.linspace(0.0,5.0,20)
arr_y1=np.array(arr_x)
arr_y2=np.array(arr_x**2)
arr_y3=np.array(arr_x**3)
ax.set(title="Linear, Quadratic, & Cubic Equations", xlabel="arr_X",
ylabel="f(arr_X)")
ax.plot(arr_x, arr_y1, label="y = arr_x", color="green", marker="v")
ax.plot(arr_x, arr_y2, label ="y = arr_x**2", color ="blue", marker="s")
ax.plot(arr_x, arr_y3, label="y = arr_x**3", color="red", marker="o")
plt.legend()
return fig
return None
multi_curve_plot()
I tried changing arr_x=np.linspace(0.0,5.0,20) to arr_x=np.linspace(0.0,5.0,25). But I want to show 25 data points on y axis without changing x-axis attributes.

Matplotlib issue x and y label for multi axes figure

import matplotlib
import matplotlib.pyplot as plt
import numpy as nm
x = nm.linspace(start=0,stop=20,num=30)
fig=plt.figure()
ax1 = fig.add_axes([0,0.6,0.6,0.4])
ax2 = fig.add_axes([0,0,0.8,0.4])
ax1.plot(x,nm.sin(x))
ax1.set_xlabel('x',fontsize=15,color='r')
ax1.set_ylabel('sin(x)',fontsize=15,color='r')
ax2.plot(x,nm.cos(x))
ax2.set_xlabel('x',fontsize=15,color='r')
ax2.set_ylabel('cos(x)',fontsize=15,color='r')
plt.show()
The output I am not able to see the xlabel for ax2 and not able to see both y label for ax1 and ax2..The image is present below:
enter code hereenter image description here
This is expected as you are asking to create an axes that is aligned with the left edge of the figure by using fig.add_axes([0,...]). Same thing for the bottom axes, which you have aligned to the bottom-left of the figure using fig.add_axes([0,0,...]).
Increase the first value e.g. fig.add_axes([0.125,...]) to leave room for the axes decorations on the left or bottom of the axes.
It is generally recommended to use the subplots functions (such as add_subplot, plt.subplots or GridSpec) so that these details are handled automatically.

Get real range in colormap with LogLocator

The following code
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import ticker
n = 50
A = np.tile(np.linspace(-26,-2,n),(n,1))
plt.figure()
plt.contourf(A)
plt.colorbar()
B = np.tile(np.logspace(-26,-2,n),(n,1))
plt.figure()
plt.contourf(B,locator=ticker.LogLocator())
plt.colorbar()
plt.show()
produces these two plots:
For the linear case (first image), every color in the colorbar is present in the image, and the min and max values of A lie respectively in the first and last color bin (going bottom to top).
For the log case (second image), the colorbar's min and max values don't make sense to me anymore.
The minimum of B is 10^-26, so this value lies at the border between the first and second color bin of the colormap, but there are none of these two first colors in the image.
The maximum of B is 10^-2, and it lies at the border between the before-before last, and the before last color bins, so it could be considered in either.
But then, why is the last (yellow) color bin here, especially since there is no yellow in the image ?
So I find the default behavior of the colormap limits (for the LogLocator) weird because it is not representative of the real (or at least approximate) data range (like in the linear case), and it adds color bins (in this case 3 : 2 below the min, and 1 above the max) that are not present in the image.
Is this a bug or is there something I didn't understand ?
#ImportanceOfBeingErnest's answer below gives the output that I want, but it just feels like I shouldn't have to do this and that I can expect the same behavior from the colormap with linear values, and from the LogLocator color mapper.
If you want to have specific intervals in your contour plot you would need to decide for them and supply them to the contouring function via the levels argument.
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import ticker
n = 50
A = np.tile(np.logspace(-26,-2,n),(n,1))
levels = 10.**np.arange(-26,-1,4)
plt.figure()
plt.contourf(A,levels=levels, locator=ticker.LogLocator())
plt.colorbar()
plt.show()

Tick labels displaying outside axis limits

Is there a way to automatically not display tick mark labels if they would protrude past the axis itself? For example, consider the following code
#!/usr/bin/python
import pylab as P, numpy as N, math as M
xvals=N.arange(-10,10,0.1)
yvals=[ M.sin(x) for x in xvals ]
P.plot( xvals, yvals )
P.show()
See how the -10 and 10 labels on the x-axis poke out to the left and right of the plot? And similar for the -1.0 and 1.0 labels on the y-axis. Can I automatically suppress plotting these but retain the ones that do not go outside the plot limits?
I think you could just format the axis ticks yourself and then prune the ones
that are hanging over. The recommended way to deal with setting up the axis is
to use the ticker API. So for example
from matplotlib.ticker import MaxNLocator
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111)
xvals=np.arange(-10,10,0.1)
yvals=[ np.sin(x) for x in xvals ]
ax.plot( xvals, yvals )
ax.xaxis.set_major_locator(MaxNLocator(prune='both'))
plt.show()
Here we are creating a figure and axes, plotting the data, and then setting the xaxis
major ticks. The formatter MaxNLocator is given the
argument prune='both' which is described in the docs here.
This is not exactly what you were asking for, but maybe it will solve your problem.

Matplotlib plotting a single line that continuously changes color

I would like to plot a curve in the (x,y) plane, where the color of the curve depends on a value of another variable T. x is a 1D numpy array, y is a 1D numpy array.
T=np.linspace(0,1,np.size(x))**2
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,y)
I want the line to change from blue to red (using RdBu colormap) depending on the value of T (one value of T exists for every (x,y) pair).
I found this, but I don't know how to warp it to my simple example. How would I use the linecollection for my example? http://matplotlib.org/examples/pylab_examples/multicolored_line.html
Thanks.
One idea could be to set the color using color=(R,G,B) then split your plot into n segments and continuously vary either one of the R, G or B (or a combinations)
import pylab as plt
import numpy as np
# Make some data
n=1000
x=np.linspace(0,100,n)
y=np.sin(x)
# Your coloring array
T=np.linspace(0,1,np.size(x))**2
fig = plt.figure()
ax = fig.add_subplot(111)
# Segment plot and color depending on T
s = 10 # Segment length
for i in range(0,n-s,s):
ax.plot(x[i:i+s+1],y[i:i+s+1],color=(0.0,0.5,T[i]))
Hope this is helpful