Artifacts in matplotlib patch plotting - matplotlib

When plotting small patch objects in matplotlib, artifacts are introduced due to the display resolution. Using anti-aliasing does not solve the problem.
Is there a solution to this problem?
import matplotlib.pyplot as plt
import matplotlib.patches as patches
ax = plt.axes()
for x in range(-10,11):
for y in range(-10,11):
rect = patches.Rectangle((x, y), width=0.1, height=0.1, color='k',aa=True)
ax.add_patch(rect)
plt.xlim([-30, 30])
plt.ylim([-30, 30])
plt.show()

Thanks for putting together a simple example of the problem - it really makes investigating this much easier!
Is there a solution to this problem?
Yes, it turns out there is! My initial guess, by just looking at the image you attached, was that there is some strange clipping/snapping going on. After ruling out the antialiasing possibility (by flicking the switch that you provided) my only other avenue of testing was to set the "snap" keyword to false (for the very limited docs on the snap method see http://matplotlib.org/api/artist_api.html#matplotlib.artist.Artist.set_snap).
Setting the snap does the trick and you end up with the expected results:
import matplotlib.pyplot as plt
import matplotlib.patches as patches
ax = plt.axes()
for x in range(-10,11):
for y in range(-10,11):
rect = patches.Rectangle((x, y), width=0.1, height=0.1,
color='k', snap=False)
ax.add_patch(rect)
plt.xlim([-30, 30])
plt.ylim([-30, 30])
plt.show()
A visual comparison (probably best opening the image in a new window as your browser will probably scale the image and introduce further visual effects):
I'm not particularly knowledgeable about the snap property in mpl and whether this is really desirable behaviour, so I will post a question on the mpl-devel mailing list to open up a conversation about this question. Hopefully this answer will help you in the meantime.

Related

How to avoid matplotlib to simplify my Y axis in figure?

the image of what I mean in my question
I'm using BMP280 to measure Temperature and Pressure using Raspberry.
I'm using matplotlib to make a graph, but the matplotlib simplify my Y axis bi adding +9.967e2.
is there any way to avoid matplotlib simplify my Y axis. Sorry I'm new to this so I don't know much.
I tried to search in google but I don't find anything. Maybe I'm using the wrong keyword as I don't know what should I search.
You can turn off the offset as shown in the examples here. For example, if you've made you plot with:
from matplotlib import pyplot as plt
plt.plot(x, y)
then you can turn off the offset with
ax = plt.gca() # get the axes object
# turn off the offset (on the y-axis only)
ax.ticklabel_format(axis="y", useOffset=False)
plt.show()
See the ticklabel_format docs for more info.

Is there a function in plotly that is equivalent to plt.axes('scaled') in matplotlib for the aspect ratio of a graph?

I want to plot some coordinates using Plotly express because it allows me a more interactive approach, but I can not find the way to control the scale in the axis in the way I can manage with matplotlib.pyplot in one single line
plt.axis("scaled")
Could you please share some suggestions? Thanks.
Here is the code using Plotly express:
fig = px.scatter(coordinates_utm, x='EASTING', y='NORTHING', title=name,
hover_name=coordinates_utm.index,
hover_data={'NORTHING':':.6f','EASTING': ':.6f'})
fig.add_trace(px.scatter(coordinates_utm_lineal, x='x', y='ylineal',color_discrete_sequence=['red']).data[0])
Here is the code using plt:
fig.show()
plt.figure()
plt.scatter(coordinates_utm_lineal.x,coordinates_utm_lineal.ylineal,s=2)
plt.scatter(coordinates_utm.EASTING,coordinates_utm.NORTHING, s=2)
plt.axis("scaled")
plt.show()
This is my current output
Sadly, you didn't provide a fully reproducible example, so I'm going to create my own.
Also, I'm not really familiar with plt.axis("scaled"), as I usually use plt.axis("equal"). Reading the documentation associated to plt.axis, they appear to be somewhat similar. See if the following answer can satisfy your needs.
import plotly.express as px
import numpy as np
t = np.linspace(0, 2*np.pi)
x = np.cos(t)
y = np.sin(t)
fig = px.scatter(x=x, y=y)
fig.layout.yaxis.scaleanchor="x"
fig.show()

Different level of transparency for edgeline and fill in matplotlib or seaborn distribution plot

I would like to set different levels of transparency (= alpha) for the edge line and fill of a distribution plot that I created in matplotlib/seaborn. For example:
ax1 = sns.distplot(BSRDI_DF, label="BsrDI", bins=newBins, kde=False,
hist_kws={"edgecolor": (1,0,0,1), "color":(1,0,0,0.25)})
The above approach does not work, unfortunately. Does anybody have any idea how I could accomplish this?
The problem seems to be that seaborn sets an alpha parameter for the histogram. While alpha defaults to None for a usual histogram, such that something like
plt.hist(x, lw=3, edgecolor=(1,0,0,0.75), color=(1,0,0,0.25))
works as expected, seaborn sets this alpha to some given value. This overwrites the alpha that is set in the RGBA tuples.
The solution is to set alpha explicitely to None:
ax = sns.distplot(x, kde=False, hist_kws={"lw":3, "edgecolor": (1,0,0,0.75),
"color":(1,0,0,0.25),"alpha":None})
A complete example:
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
x = np.random.randn(60)
ax = sns.distplot(x, label="BsrDI", bins=np.linspace(-3,3,10), kde=False,
hist_kws={"lw":3, "edgecolor": (1,0,0,0.75),
"color":(1,0,0,0.25),"alpha":None})
plt.show()
EDIT Nevermind, I thought using color instead of facecolor was causing the problem but it seems the output that I got only looked right because the patches were overlapping, giving seemingly darker edges.
After investigating the issue further, it looks like seaborn is hard-setting the alpha level at 0.4, which supersedes the arguments passed to hist_kws=
sns.distplot(x, kde=False, hist_kws={"edgecolor": (1,0,0,1), "lw":5, "facecolor":(0,1,0,0.1), "rwidth":0.8})
While using the same parameters to plt.hist() gives:
plt.hist(x, edgecolor=(1,0,0,1), lw=5, facecolor=(0,1,0,0.1), rwidth=0.8)
Conclusion: if you want different alpha levels for edges and face colors, you'll have to use matplotlib directly, and not seaborn.

Usetex in Matplotlib

When I try to obtain plots in which the axis (both formulae and text) are written in LaTeX standard roman font, I keep not obtaining the plot, but the code runs without warnings. In particular, this simple scatter with TeX code in the axis labels, in which I have put my better understanding of the documentation:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
x = np.linspace(0,1,100)
y = np.random.rand(100,1)
plt.rc('text', usetex=True)
plt.rc('font', family='roman')
plt.scatter(x, y, c='b', s=10)
plt.xlabel(r'$\lambda$ ($\AA$)',size='12')
plt.ylabel(r'$F_\alpha (W/m^2)$ ',size='12')
plt.title(r'A title in \LaTeX typography')
plt.show()
keeps yielding a message like <matplotlib.figure.Figure at 0x1f75d4750>, which I have met before, but I keep failing when trying to remedy this one. In addition, saving the plot (png or pdf) would not solve the issue, and if the problem is related to TeX, I have definitely not found any resource that can help. I use MacOS Sierra.

Interactive image plotting with matplotlib

I am transitioning from Matlab to NumPy/matplotlib. A feature in matplotlib that seems to be lacking is interactive plotting. Zooming and panning is useful, but a frequent use case for me is this:
I plot a grayscale image using imshow() (both Matlab and matplotlib do well at this). In the figure that comes up, I'd like to pinpoint a certain pixel (its x and y coordinates) and get its value.
This is easy to do in the Matlab figure, but is there a way to do this in matplotlib?
This appears to be close, but doesn't seem to be meant for images.
custom event handlers are what you are going to need for this. It's not hard, but it's not "it just works" either.
This question seems pretty close to what you are after. If you need any clarification, I'd be happy to add more info.
I'm sure you have managed to do this already. Slightly(!) modifying the link, I've written the following code that gives you the x and y coordinates once clicked within the drawing area.
from pylab import *
import sys
from numpy import *
from matplotlib import pyplot
class Test:
def __init__(self, x, y):
self.x = x
self.y = y
def __call__(self,event):
if event.inaxes:
print("Inside drawing area!")
print("x: ", event.x)
print("y: ", event.y)
else:
print("Outside drawing area!")
if __name__ == '__main__':
x = range(10)
y = range(10)
fig = pyplot.figure("Test Interactive")
pyplot.scatter(x,y)
test = Test(x,y)
connect('button_press_event',test)
pyplot.show()
Additionally, this should make it easier to understand the basics of interactive plotting than the one provided in the cookbook link.
P.S.: This program would provide the exact pixel location. The value at that location should give us the grayscale value of respective pixel.
Also the following could help:
http://matplotlib.sourceforge.net/users/image_tutorial.html