Is it possible to specify a position in terms of Scaled coordinates in one direction and use the ordinary coordinates from my data points in the other direction on the plot? In other words, I want to specify a position, where the x coordinate is an ordinary coordinate and will change position in the plot if the plot range is changed, but the y coordinate is Scaled coordinate and will remain at a fixed height relative to the plot.
It is a bit late in coming, but is this what you are looking for?
data = {{1, 0.5}, {2, 0.7}, {3, 0.4}, {4, 0.2}};
Graphics[
Line[data /. {x_, y_} :> Scaled[{0, y}, {x, 0}]],
Axes -> True,
PlotRange -> {Automatic, {0, 100}},
AspectRatio -> Full
]
Related
Let us assume that we have camera extrinsics [R|t](camera-to-world) and a permutation matrix P that flips or changes the axis, which may have variants regarding its determinant. For example, this
P = np.array([
[1, 0, 0],
[0, 0, 1],
[0, -1, 0]
]) # (sorry that I'm not writing in consistent manner.)
changes points(axis) (x, y, z) to (x, z, -y). This may affect the rotation matrix in new coordinate system, if my guess is correct, so that it results in a new rotation matrix R' that decides the orientation of the transformed camera. Is it just P[R|t] and I get R' = PR? How do I find this?
Fliping odd number of axises is not rotation ! But that does not matter you can use matrix inverse to compute this so if I see it correctly you have:
R' = R*P
Where R' is your new matrix (fliped) and R is original matrix and you want to know the P so:
R' = R*P // Inverse(R)*
Inverse(R)*R' = Inverse(R)*R*P
Inverse(R)*R' = P
In case your R is orthonormal then Inverse of it is the same as its Transponation which is way faster. If its just ortogonal you can still use Transpose instead of Inverse but you would need to correct the basis vector lenghts afterwards.
I have 3 lists with some strings on it:
high = ['string1','string2','string3']
med = ['string4','string5','string6']
low = ['string7','string8','string9']
I want to make a plot like the one below:
It can be any geometric form but I want to put inside them the string from the 3 lists:
red form gets high list's strings
yellow form gets med list's strings
green form gets low list's string
I have no idea where to start if someone can help me with this, i appreciate
Here's how I approached it:
I have used the Plotly Library shapes to create rectangles and text as points on the axis, you can use the same approach on Seaborn and Matplotlib.
You can create the texts labels on the plot the following way:
fig.add_trace(go.Scatter( x=[0, 0, 0],
y=[3, 0, -3],
text=["red form gets high list's strings",
"yellow form gets med list's strings",
"green form gets low list's string"],
mode="text",
textfont=dict(color="black", size=18,family="Arail",)))
Recatangle shapes for corresponding text coordinates can be created as follows:
fig.add_shape(type="rect",
line_color="gray", fillcolor="red",
x0= <Fixed x0 coordinate point>,
y0= <desired y0 coordinate point>, x1= <Fixed x2 coordinate point>, y1=<Desired y1 coordinate point>)
Moreover, I have updated the figure to hide the axis and ticks
Full code below:
import plotly.graph_objects as go
fig = go.Figure()
# Creating scatter trace of text labels
fig.add_trace(go.Scatter( x=[0, 0, 0],
y=[3, 0, -3],
text=["red form gets high list's strings",
"yellow form gets med list's strings",
"green form gets low list's string"],
mode="text",
textfont=dict(color="black", size=18,family="Arail",)))
# Update axes properties
fig.update_xaxes(showticklabels=False,
showgrid=False, zeroline=False,)
fig.update_yaxes(showticklabels=False,
showgrid=False, zeroline=False,)
#x co-ordinate points
rect_x0, rect_x1 = -2, 2
# Add rectangles
fig.add_shape(type="rect",
line_color="gray", fillcolor="red",
x0= rect_x0, y0=2, x1= rect_x1, y1=4)
fig.add_shape(type="rect",
line_color="gray", fillcolor="green",
x0= rect_x0, y0=-1, x1= rect_x1, y1=1)
fig.add_shape(type="rect",
line_color="gray", fillcolor="yellow",
x0= rect_x0, y0=-4, x1= rect_x1, y1=-2)
fig.update_shapes(opacity=0.3, xref="x", yref="y")
fig.update_layout(margin=dict(l=20, r=20, b=100),
height=600, width=800,
plot_bgcolor="white")
fig.show()
Result
I have a dataframe with three features: DEPTH, PERMEABILITY and POROSITY. And I would like to plot DEPTH at y axis and PERMEABILITY and POROSITY together at x axis, although these last two features have different scales.
df = pd.DataFrame({'DEPTH(m)': [100, 150, 200, 250, 300, 350, 400, 450, 500, 550],
'PERMEABILITY(mD)': [1000, 800, 900, 600, 200, 250, 400, 300, 100, 200],
'POROSITY(%)': [0.30, 0.25, 0.15, 0.19, 0.15, 0.10, 0.15, 0.19, 0.10, 0.15]})
I already managed to plot them together, but now I need to fill with two different colors the areas between the curves. For example, when PERMEABILITY curve is on the right side of POROSITY, the area between them should be green. If PERMEABILITY is on the left side, the area between curves should be yellow.
f, ax1 = plt.subplots()
ax1.set_xlabel('PERMEABILITY(mD)')
ax1.set_ylabel('DEPTH(m)')
ax1.set_ylim(df['DEPTH(m)'].max(), df['DEPTH(m)'].min())
ax1.plot(df['PERMEABILITY(mD)'], df['DEPTH(m)'], color='red')
ax1.tick_params(axis='x', labelcolor='red')
ax2 = ax1.twiny()
ax2.set_xlabel('POROSITY(%)')
ax2.plot(df['POROSITY(%)'], df['DEPTH(m)'], color='blue')
ax2.tick_params(axis='x', labelcolor='blue')
So the right output should be like this: (Sorry for the Paint image below)
Anyone could help me with this?
You can use the fill_betweenx() function, however you need to convert one of your axis to the scale of the other one, because you use twiny. Below, I converted your POROSITY data to fit to the axis of PERMEABILITY.
Then you can use two conditional fill_betweenx, where the two curves are larger than each other, to assign different colors to those patches. Also, since your data is discrete, you need to set interpolate=True in your fill_betweenx functions.
f, ax1 = plt.subplots()
ax1.set_xlabel('PERMEABILITY(mD)')
ax1.set_ylabel('DEPTH(m)')
ax1.set_ylim(df['DEPTH(m)'].max(), df['DEPTH(m)'].min())
ax1.plot(df['PERMEABILITY(mD)'], df['DEPTH(m)'], color='red')
ax1.tick_params(axis='x', labelcolor='red')
ax2 = ax1.twiny()
ax2.set_xlabel('POROSITY(%)')
ax2.plot(df['POROSITY(%)'], df['DEPTH(m)'], color='blue')
ax2.tick_params(axis='x', labelcolor='blue')
# convert POROSITY axis to PERMEABILITY
# value-min / range -> normalized POROSITY (normp)
# normp*newrange + newmin -> stretched POROSITY to PERMEABILITY
z=df['POROSITY(%)']
x=df['PERMEABILITY(mD)']
nz=((z-np.min(z))/(np.max(z)-np.min(z)))*(np.max(x)-np.min(x))+np.min(x)
# fill between in green where PERMEABILITY is larger
ax1.fill_betweenx(df['DEPTH(m)'],x,nz,where=x>=nz,interpolate=True,color='g')
# fill between in yellow where POROSITY is larger
ax1.fill_betweenx(df['DEPTH(m)'],x,nz,where=x<=nz,interpolate=True,color='y')
plt.show()
The result is as below (I might have used different colors, but I assume that's not a concern).
I wrote a Python script based on matplotlib that generates curves based on a common timeline. The number of curves sharing the same x axis in my plot can vary from 1 to 6 depending on user options.
Each of the data plotted use different y scales and require a different axis for drawing. As a result, I may need to draw up to 5 different Y axes on the right of my plot. I found the way in some other post to offset the position of the axes as I add new ones, but I still have two issues:
How to control the position of the multiple axes so that the tick labels don't overlap?
How to control the position of each axis label so that it is placed vertically at the bottom of each axis? And how to preserve this alignment as the display window is resized, zoomed-in etc...
I probably need to write some code that will first query the position of the axis and then a directive that will place the label relative to that position but I really have no idea how to do that.
I cannot share my entire code because it is too big, but I derived it from the code in this example. I modified that example by adding one extra plot and one extra axis to more closely match what intend to do in my script.
import matplotlib.pyplot as plt
def make_patch_spines_invisible(ax):
ax.set_frame_on(True)
ax.patch.set_visible(False)
for sp in ax.spines.values():
sp.set_visible(False)
fig, host = plt.subplots()
fig.subplots_adjust(right=0.75)
par1 = host.twinx()
par2 = host.twinx()
par3 = host.twinx()
# Offset the right spine of par2. The ticks and label have already been
# placed on the right by twinx above.
par2.spines["right"].set_position(("axes", 1.2))
# Having been created by twinx, par2 has its frame off, so the line of its
# detached spine is invisible. First, activate the frame but make the patch
# and spines invisible.
make_patch_spines_invisible(par2)
# Second, show the right spine.
par2.spines["right"].set_visible(True)
par3.spines["right"].set_position(("axes", 1.4))
make_patch_spines_invisible(par3)
par3.spines["right"].set_visible(True)
p1, = host.plot([0, 1, 2], [0, 1, 2], "b-", label="Density")
p2, = par1.plot([0, 1, 2], [0, 3, 2], "r-", label="Temperature")
p3, = par2.plot([0, 1, 2], [50, 30, 15], "g-", label="Velocity")
p4, = par3.plot([0,0.5,1,1.44,2],[100, 102, 104, 108, 110], "m-", label="Acceleration")
host.set_xlim(0, 2)
host.set_ylim(0, 2)
par1.set_ylim(0, 4)
par2.set_ylim(1, 65)
host.set_xlabel("Distance")
host.set_ylabel("Density")
par1.set_ylabel("Temperature")
par2.set_ylabel("Velocity")
par3.set_ylabel("Acceleration")
host.yaxis.label.set_color(p1.get_color())
par1.yaxis.label.set_color(p2.get_color())
par2.yaxis.label.set_color(p3.get_color())
par3.yaxis.label.set_color(p4.get_color())
tkw = dict(size=4, width=1.5)
host.tick_params(axis='y', colors=p1.get_color(), **tkw)
par1.tick_params(axis='y', colors=p2.get_color(), **tkw)
par2.tick_params(axis='y', colors=p3.get_color(), **tkw)
par3.tick_params(axis='y', colors=p4.get_color(), **tkw)
host.tick_params(axis='x', **tkw)
lines = [p1, p2, p3, p4]
host.legend(lines, [l.get_label() for l in lines])
# fourth y axis is not shown unless I add this line
plt.tight_layout()
plt.show()
When I run this, I obtain the following plot:
output from above script
In this image, question 2 above means that I would want the y-axis labels 'Temperature', 'Velocity', 'Acceleration' to be drawn directly below each of the corresponding axis.
Thanks in advance for any help.
Regards,
L.
What worked for me was ImportanceOfBeingErnest's suggestion of using text (with a line like
host.text(1.2, 0, "Velocity" , ha="left", va="top", rotation=90,
transform=host.transAxes))
instead of trying to control the label position.
How can I make a polar contour plot in Maxima? Given an expression such as
exp(-r) * cos(phi)
I'd like to plot contours in the x-y plane which have the same value of the expression at all points along the contour.
I've tried
draw3d(cylindrical(exp(-r) * cos(phi), r, 0, 5, phi, 0, 2*%pi), contour=map))
but cylindrical plots r as a function of z and phi, not z as a function of r and phi. It would be nice to not have to convert manually to Cartesian coordinates.
contour_plot(exp(-r)*cos(phi), [r,0,2], [phi, 0, 2*%pi], [transform_xy, polar_to_xy],
[gnuplot_preamble, "set cntrparam levels 10;"]);
The polar_to_xy option interprets the first two variables as distance from the z axis and azimuthal angle.
What is the problem using something like
draw3d(explicit(20*exp(-x^2-y^2)-10,x,0,2,y,-3,3),
contour_levels = 15,
contour = map,
surface_hide = true) ;
I think that in that case is straigthforward to do it.