Jupyter Notebook运行Matplotlib自定义标记脚本报类型错误,IDLE正常
Hey there, let's break down why this error pops up in Jupyter but works in IDLE, and how to fix it.
First, the root cause of that TypeError is super straightforward: when you use randint(0, len(markers), 1) in your code, you're getting a numpy array object (like array([3])) instead of a plain integer. Python lists (your markers list) only accept single integer scalars as indices, hence the "only integer scalar arrays can be converted to a scalar index" error.
Why does this work in IDLE but not Jupyter?
The key difference is where your randint function is coming from in each environment:
- In IDLE, you're probably importing Python's built-in
random.randint(viafrom random import randint). This function only takes two arguments (randint(a, b)) and returns a single integer betweenaandb(inclusive). It doesn't support the thirdsizeparameter, so if your code worked there, you might have either omitted thesize=1in that version, or accidentally used the standard library's implementation without realizing it. - In Jupyter, though, you're almost certainly using
numpy.randint(either viafrom numpy import randintor a previous cell that imported numpy into the global namespace). Numpy'srandintdoes accept asizeparameter—and when you passsize=1, it returns a 1-element numpy array, not a plain integer. That's why indexing yourmarkerslist fails here.
Fixes you can apply right away
You've got a couple of simple options to fix this across both environments:
Option 1: Ditch the size parameter (cleanest approach)
Since you only need one random integer, just remove the size=1 argument. Note that numpy's randint uses a half-open interval ([low, high)), so you'll need to adjust the upper bound to avoid index errors:
# Original code (causes error in Jupyter) return "$"+markers[randint(0,len(markers),1)]+"$" # Fixed version (works with numpy.randint) return "$"+markers[randint(0, len(markers))]+"$" # Do the same for markersize: markersize=randint(16,26) # This gives integers from 16 to 25; if you want up to 26, use randint(16,27)
If you prefer using Python's standard library random.randint (which uses a closed interval), make sure to import it explicitly and adjust the bounds:
from random import randint # Fixed code for random.randint return "$"+markers[randint(0, len(markers)-1)]+"$" markersize=randint(16,26) # This gives integers from 16 to 26 inclusive
Option 2: Convert the numpy array to a scalar
If you really need to keep the size=1 parameter for some reason, use the .item() method to extract the single integer from the numpy array:
return "$"+markers[randint(0, len(markers), 1).item()]+"$" markersize=randint(16,26,1).item()
Pro tip to avoid future environment conflicts
Always explicitly import the randint you want at the top of your script, instead of relying on implicit imports. This way, your code behaves the same no matter where you run it:
# For numpy's randint import numpy as np # Then use np.randint(...) everywhere # OR for Python's standard library randint from random import randint # Then use randint(...) everywhere
内容的提问来源于stack exchange,提问作者Luckylu

