This will cover performance, as well as Python style.
Save constants in one place
You currently have the magic numbers 2000 and 3000, the resolution of your image. Save these to variables perhaps named X, Y or W, H.
Mention your requirements
You don't just rely on Python 3 and Jupyter - you rely on numpy and pillow. These should go in a requirements.txt if you don't already have one.
Don't save your complex grid
At all. complex_number should be formed dynamically in the loop based on range expressions.
Disclaimer: if you're vectorizing (which you should do), then the opposite applies - you would keep your complex grid, and lose some loops.
Don't use index lookups
You're using index to get your coordinates. Don't do this - form the coordinates in your loops, as well.
Mandelbrot is symmetrical
Notice that it's mirror-imaged. This means you can halve your computation time and save every pixel to the top and bottom half.
In a bit I'll show some example code accommodating all of the suggestions above. Just do (nearly) what @Alex says and I'd gotten halfway through implementing, with one difference: accommodate the symmetry optimization I described.