matplotlib draw ellipse contour - matplotlib

I am trying to draw something similar:
The main idea is to draw ellipses with different color in some specific range, for example from [-6, 6].
I have understood that plt.contour function can be used. But I do not understand how to generate lines.

I personally wouldn't do this with contour as you then need to add information about the elevation which I don't think you want?
matplotlib has Ellipse which is a subclass of Artist. The following example adds a single ellipse to a plot.
import matplotlib as mpl
ellipse = mpl.patches.Ellipse(xy=(0, 0), width=2.0, height=1.0)
fig, ax = plt.subplots()
fig.gca().add_artist(ellipse)
ax.set_aspect('equal')
ax.set_xlim(-2, 2)
ax.set_ylim(-2, 2)
You then need to research how to get the effect you are looking for, I would have a read of the docs in general making things transparent is done through alpha.

Related

Matplotlib widget, secondary y axis, twinx

i use jupyterlab together with matplotlib widgets. I have ipywidgets installed.
My goal is to choose which y-axis data is displayed in the bottom of the figure.
When i use the interactive tool to see the coordinates i get only the data of the right y-axis displayed. Both would be really nice^^ My minimal code example:
import matplotlib.pyplot as plt
import numpy as np
%matplotlib widgets
x=np.linspace(0,100)
y=x**2
y2=x**3
fig,ax=plt.subplots()
ax2=ax.twinx()
ax.plot(x,y)
ax2.plot(x,y2)
plt.show()
With this example you might ask why not to plot them to the same y-axis but thats why it is a minimal example. I would like to plot data of different units.
To choose which y-axis is used, you can set the zorder property of the axes containing this y-axis to a higher value than that of the other axes (0 is the default):
ax.zorder = 1
However, that will cause this Axes to obscure the other Axes. To counteract this, use
ax.set_facecolor((0, 0, 0, 0))
to make the background color of this Axes transparent.
Alternatively, use the grab_mouse function of the figure canvas:
fig.canvas.grab_mouse(ax)
See here for the (minimal) documentation for grab_mouse.
The reason this works is this:
The coordinate line shown below the figure is obtained by an event callback which ultimately calls matplotlib.Axes.format_coord() on the axes instance returned by the inaxes property of the matplotlib events that are being generated by your mouse movement. This Axes is the one returned by FigureCanvasBase.inaxes() which uses the Axes zorder, and in case of ties, chooses the last Axes created.
However, you can tell the figure canvas that one Axes should receive all mouse events, in which case this Axes is also set as the inaxes property of generated events (see the code).
I have not found a clean way to make the display show data from both Axes. The only solution I have found would be to monkey-patch NavigationToolbar2._mouse_event_to_message (also here) to do what you want.

How to Superimpose on Matplotlib

I want to draw a triangle with two points inside using matplotlib. Here is the code I'm using:
plt.figure()
triangleEdges = np.array([[0,0],[1,0],[0.5,0.5*np.sqrt(3)]])
colors = ['red', 'green', 'blue']
t1 = plt.Polygon(triangleEdges, facecolor="none",
edgecolor='black', linewidth=2)
t1.set_facecolor('xkcd:salmon')
plt.gca().add_patch(t1)
drawSoftmaxPoint('blue',100,np.array([0.2,0.1,0.7]) )
drawSoftmaxPoint('red',100,np.array([0.5,0.1,0.7]))
plt.show()
Picture
According to the code, there should be two points inside the triangle, but it looks like the background is covering them. How can I make them visible?
Thank you!
you could use alpha and z-order in your polygon to make it happen (from the doc of matplotlib). just try to set the alpha value between 0 and 1 to check if you can see your points. and then maybe use z-order on your different elements to make sure the fill of the polygon is deepest (most behind). example of zorder:
https://matplotlib.org/gallery/misc/zorder_demo.html

Relocating legend from GeoPandas plot

I'm plotting a map with legends using the GeoPandas plotting function. When I plot, my legends appear in the upper right corner of the figure. Here is how it looks like:
I wanted to move the legends to the lower part of the graph. I would normally would have done something like this for a normal matplotlib plot:
fig, ax = plt.subplots(1, figsize=(4.5,10))
lima_bank_num.plot(ax=ax, column='quant_cuts', cmap='Blues', alpha=1, legend=True)
ax.legend(loc='lower left')
However, this modification is not taken into account.
This could be done using the legend_kwds argument:
df.plot(column='values', legend=True, legend_kwds={'loc': 'lower right'});
You can access the legend defined on the ax instance with ax.get_legend(). You can then update the location of the legend using the method set_bbox_to_anchor. This doesn't provide the same ease of use as the loc keyword when creating a legend from scratch, but does give control over placement. So, for your example, something like:
leg = ax.get_legend()
leg.set_bbox_to_anchor((0., 0., 0.2, 0.2))
A bit of documentation of set_bbox_to_anchor, though I don't find it extraordinarily helpful.
If you have a horizontal legend and you're trying to simply reduce the gap between the legend and plot, I recommend the colorbar approach detailed at https://gis.stackexchange.com/a/330175/32531 along with passing the pad legend_kwd argument:
legend_kwds={"orientation": "horizontal", "pad": 0.01}

PyPlot in Juno: Fixing axis height

I apologise if this has already been asked, I've searched long and hard on this site and couldn't find anything that worked. I'm using Julia, specifically the Juno IDE, and I am trying to use PyPlot to create my graphs. I wanted to set the y axis height when plotting, but leave the x axis variable. Here is the code I have been using to generate my plots
fig = figure()
ax = fig[:add_axes]
BEFE250 = (plot(s1, s2, lw=1.0, "-", color="b"))
ylabel("u(x,t)", size=20)
xlabel("t", size=20)
gcf()
which gives me
However, I need space in the top left corner as I am going to layer another picture on top in latex. So I need to set the y-axis height to between -3 and 3. However, if I set the axes height in PyPlot
fig = figure()
ax = fig[:add_axes]([0.1, 0.1, -3.0, 3.0])
BEFE250 = (plot(s1, s2, lw=1.0, "-", color="b"))
ylabel("u(x,t)", size=20)
xlabel("t", size=20)
gcf()
then it switches the orientation of the x-axis. If I set the axis height after running the plot, PyPlot puts the picture in a box in a legend off to the side of the main picture, and the main picture is empty? If someone could help me out it would be greatly appreciated.
Thanks for your help.
EDIT: Using xlim=(-10.,10.) and ylim=(-2.,12.) doesn't work either. PyPlot still adapts the axes to the data.
Try xlim(-10, 10) and ylim(-2, 12) after the plot command:
plot(s1, s2, lw=1.0, "-", color="b")
ylim(-3, 3)
Just try this, without the add_axes.
You probably also want LaTeX labels -- just add an L before the string, which gives a special LaTeX string from the LaTeXString package. You can either just add the L, or add $ inside too:
ylabel(L"u(x,t)", size=20)
ylabel(L"$u(x,t)$", size=20)
[The $ are necessary in certain circumstances that I forget.]
I'm not sure how good the PyPlot support is in Juno.
You might want to try this in IJulia.
By the way, is there a reason you want to layer on a separate figure in LaTeX? That might not be the best way to do it.

How can I draw axes with a 45 degree rotation?

I have a set of 7x4 plots arranged in a grid using subplot. I now want to add diagonal axes on top of these.
I know you can superpose axes on top of previously made subplots by setting the background to 'none':
ax = fig.add_subplot(111)
ax.set_axis_bgcolor('none')
But I can't find a rotated axis thing. Currently I'm trying to use a top view 3D axes, but I'm far from a usable solution there.
I'm willing to accept drawing the axis+ticks by hand, if this is the only way possible.
EDIT: using the floating_axis module, I was able to draw rotated (and sheared) axes, but unable to edit the ticks, which is very necessary for what I need. The following snippet demonstrates adding a floating_axis to an existing figure fig. Any manipulation of the axes' ticks fails.
from matplotlib.transforms import Affine2D
import mpl_toolkits.axisartist.floating_axes as floating_axes
trafo = Affine2D().skew_deg(-10,-10).rotate_deg(45)
grid_helper = floating_axes.GridHelperCurveLinear(trafo, extremes=(0, 4, 0, 4))
artistax = floating_axes.FloatingSubplot(fig, 111, grid_helper=grid_helper)
artistax.set_axis_bgcolor('none')
artistax.axis["top"].set_visible(False)
artistax.axis["right"].set_visible(False)
fig.add_subplot(artistax)