contour_plot with several poles

I have a 2d function with four poles that i would like to exclude from the plot because they hide interesting details of the rest of the plot. With just one pole i can omit one region. Now I want to omit all four like this:

show( contour_plot(pic, (x,-0.5,1.5), (z,-1,2), region=[((x)^2+(z)^2-.01), ((x)^2+(z-1)^2-.01), ((x-1)^2+(z)^2-.01), ((x-1)^2+(z-1)^2-.01)] ) )

that means i give a list of regions. That fails:

Traceback (most recent call last):
File "e-feld.sage.py", line 68, in <module>
show( contour_plot(pic, (x,-_sage_const_0p5 ,_sage_const_1p5 ), (z,-_sage_const_1 ,_sage_const_2 ), region=[((x)**_sage_const_2 +(z)**_sage_const_2 -_sage_const_p01 ), ((x)**_sage_const_2 +(z-_sage_const_1 )**_sage_const_2 -_sage_const_p01 ), ((x-_sage_const_1 )**_sage_const_2 +(z)**_sage_const_2 -_sage_const_p01 ), ((x-_sage_const_1 )**_sage_const_2 +(z-_sage_const_1 )**_sage_const_2 -_sage_const_p01 )] ) )
File "/usr/lib/python2.7/dist-packages/sage/misc/decorators.py", line 411, in wrapper
return func(*args, **kwds)
File "/usr/lib/python2.7/dist-packages/sage/misc/decorators.py", line 411, in wrapper
return func(*args, **kwds)
File "/usr/lib/python2.7/dist-packages/sage/misc/decorators.py", line 492, in wrapper
return func(*args, **options)
File "/usr/lib/python2.7/dist-packages/sage/plot/contour_plot.py", line 848, in contour_plot
include_endpoint=True)],
TypeError: 'tuple' object is not callable

Is it my syntax? Can I give a list of regions, at all? Or can I tone down the poles in some other way so that i can still see the contours of my plot?

edit retag close merge delete

Sort by » oldest newest most voted (I'd tried to write the following lines as comments to @Emmanuel Charpentier's answer, but I had problems with formatting)

In the preceding answer, I think that the correct syntax is lambda x,z: (x^2+z^2.... Perhaps it is clearer to define before the region to be included. In order to color the excluded region, you can also plot it with region_plot and then combine everything in a single figure. Try, for example, the following complete example:

# Variables
var("x,y")

# f is a function with poles in (0,0), (1,0), (0,1), (1,1)
f(x,y) = 1/(x^2+y^2) + 1/((x-1)^2+y^2) + 1/(x^2+(y-1)^2) + 1/((x-1)^2+(y-1)^2)

# Region where contour lines should be plotted
def region_to_include(x,y):
return x^2+y^2>0.1 and x^2+(y-1)^2>0.1 and (x-1)^2+y^2>0.1 and (x-1)^2+(y-1)^2>0.1

# As an alternative:
#def region_to_include(x,y):
#    return (x^2+y^2-0.1) * (x^2+(y-1)^2-0.1) * ((x-1)^2+y^2-0.1) * ((x-1)^2+(y-1)^2-0.1)

# Region to be excluded
def region_to_exclude(x,y):
return not region_to_include(x,y)

# Contour plot on the desired region
c = contour_plot(f(x,y), (x,-1,2), (y,-1,2), region=region_to_include,
contours= 30, plot_points=200, cmap=colormaps.jet, colorbar=True)

# Plot of the region to be excluded
r = region_plot(region_to_exclude, (x,-1,2), (y,-1,2),
plot_points=300, incol="gray", bordercol="black", borderwidth=3)

# Final plot
show(c + r, frame=True, axes=False)

See this SageCell

more

don't i do exactly what you do, in your example? why goes wrong with the poles on the left?

Since you don't provide the exact definition of the function whose contours you try to plot, I can't tell what happens in every pole.

no, it was not a problem with the poles but a typo on my part. your example is perfectly fine but i had a .1 instead of 1, which made it miss the left poles.

From the docstring:

""region" - (default: None) If region is given, it must be a function of two variables. Only segments of the surface where region(x,y) returns a number >0 will be included in the plot."

Your region argument is a list of four expressions. Apparently, you wish to exclude the neighborhood of{(0, 0),(0,1),(1, 0), (1,1)}. I'd try:

region=lambda x,z: (x^2+z^2)>1/100)*(((x-1)^2+z^2)>1/100)*(x^2+(z-1)^2)>1/100)*(((x-1)^2+(z-1)^2)>1/100)

which should return True (i. e. 1) except in the target neighborhoods, where it should return 0.

HTH,

EDIT : lambda x, z:..., **NOT**lambda(x,z)...`. My deepest apologies.

more

awesome, thank you for the idea to put this into a lambda function.