You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm reporting this for Python 3.9.13 with matplotlib 3.8.1
Problem Description
I tried to run the command make_scatter_glow on a plot where I plotted a few scatter points before I also added lines, a fill_between, and many more. When I ran make_scatter_glow at the end, I got the following error:
File "...", line 222, in make_scatter_glow
x, y = scatterpoints.get_offsets().data.T
AttributeError: 'memoryview' object has no attribute 'T'
Besides, I noticed that it only makes the first scatter series glow (if it detects one) and that the color of the glow does not match the color of the scatter series if it does not originate from a colormap, but a static color. When I get the plotting of multiple series right, it still looks like:
for
# Importsimportnumpyasnpimportmatplotlib.pyplotasplt# Create a figure and axesfig, ax=plt.subplots()
# scattering three random series_=ax.scatter(x=[1, 2, 3], y=[1, 2, 3]) # has default blue glow and thus works out by first look_=ax.scatter(x=[1, 2, 3], y=[3, 2, 1]) # glow did not show at first; when fixed the glow was blue as well_=ax.scatter( # glow did not show at first; when fixed the glow had the correct colors for each pointx=np.random.rand(10),
y=np.random.rand(10),
c=np.arange(10),
)
Suspected Cause
I'm not 100% familiar with Axes.collection in matplotlib, but I think the error is coming from the way how the collection is picked because it by default takes the last one. I marked the problematic line together with the ones causing the wrong color and the missing glows with a ⚠️.
defmake_scatter_glow(
ax: Optional[plt.Axes] =None,
n_glow_lines: int=10,
diff_dotwidth: float=1.2,
alpha: float=0.3,
) ->None:
"""Add glow effect to dots in scatter plot. Each plot is redrawn 10 times with increasing width to create glow effect."""ifnotax:
ax=plt.gca()
scatterpoints=ax.collections[-1] # <-- ⚠️ I ASSUME THIS CAUSES THE ISSUE OF THE CRASH OF THE NEXT LINEx, y=scatterpoints.get_offsets().data.Tdot_color=scatterpoints.get_array() # <-- ⚠️ THIS RETURNS None IF NOT FROM A COLORMAP AND THUS CAUSES WRONG COLORdot_size=scatterpoints.get_sizes()
alpha=alpha/n_glow_linesforiinrange(1, n_glow_lines):
plt.scatter(x, y, s=dot_size*(diff_dotwidth**i), c=dot_color, alpha=alpha)
# ⚠️ THIS DOES NOT SEEM TO PLOT ANY SERIES BUT THE FIRST ONE (IF ONE CAN BE DETECTED)
Proposed Fix
I could work out a solution that first collects the information of all scatter series and then plots the glows one by one:
defmake_scatter_glow(
ax: Optional[plt.Axes] =None,
n_glow_lines: int=10,
diff_dotwidth: float=1.2,
alpha: float=0.3,
) ->None:
"""Add glow effect to dots in scatter plot. Each plot is redrawn 10 times with increasing width to create glow effect."""ifnotax:
ax=plt.gca()
# first, the details of each scatter series are stored in a listalpha=alpha/n_glow_linesscatter_series= []
forcollectioninax.collections:
ifisinstance(collection, mpl.collections.PathCollection): # True for scatter seriesdot_colors=collection.get_array()
ifdot_colorsisNone: # the "if not" does not work because this can be a NumPy-Array which has no such comparisondot_colors=collection.get_facecolors()
scatter_details= {
'offsets': collection.get_offsets().data.T,
'dot_colors': dot_colors,
'sizes': collection.get_sizes()
}
scatter_series.append(scatter_details)
# then, the scatter series are augmented by the glow effectforseriesinscatter_series:
x, y=series['offsets']
dot_colors=series['dot_colors']
dot_size=series['sizes']
# Apply glowforiinrange(0, n_glow_lines):
ax.scatter(x, y, s=dot_size*(diff_dotwidth**i), c=dot_colors, alpha=alpha)
Now, with this function, there are no crashes even though multiple collections are present (lines, scatter, etc. at arbitrary order), the color is correct, and all glows are applied.
I did not start a pull request since matplotlib details are a bit outside my domain 😅
The text was updated successfully, but these errors were encountered:
@IruNikZe I noticed this too when implementing glow effects for 3D scatters. eaa1429
A similar idea to the one you stated is to call is to simply use your own function for making the axis glow (which looks like you have already done). This is how I went about it.
# function to make 2d or 3d scatters glowdefmake_collection_glow(ax, collection, mode="3d"):
ifmode=="3d":
x, y, z=collection._offsets3delifmode=="2d":
x, y=collection.get_offsets().data.Tdot_color=collection.get_facecolor()
dot_size=collection.get_sizes()
alpha=0.2/10ifmode=="3d":
for_inrange(1, 10):
ax.scatter(x, y, z, s=dot_size*(1.2**_), c=dot_color, alpha=alpha)
elifmode=="2d":
for_inrange(1, 10):
ax.scatter(x, y, s=dot_size*(1.2**_), c=dot_color, alpha=alpha)
# after you have created the scatterforidx, collectioninenumerate(ax.collections):
make_collection_glow(ax, collection, mode="2d")
Hello,
I'm reporting this for Python 3.9.13 with
matplotlib
3.8.1Problem Description
I tried to run the command
make_scatter_glow
on a plot where I plotted a few scatter points before I also added lines, a fill_between, and many more. When I ranmake_scatter_glow
at the end, I got the following error:Besides, I noticed that it only makes the first scatter series glow (if it detects one) and that the color of the glow does not match the color of the scatter series if it does not originate from a colormap, but a static color. When I get the plotting of multiple series right, it still looks like:
for
Suspected Cause
I'm not 100% familiar with⚠️ .
Axes.collection
inmatplotlib
, but I think the error is coming from the way how the collection is picked because it by default takes the last one. I marked the problematic line together with the ones causing the wrong color and the missing glows with aProposed Fix
I could work out a solution that first collects the information of all scatter series and then plots the glows one by one:
Now, with this function, there are no crashes even though multiple collections are present (lines, scatter, etc. at arbitrary order), the color is correct, and all glows are applied.
I did not start a pull request since
matplotlib
details are a bit outside my domain 😅The text was updated successfully, but these errors were encountered: