0

I'm trying to plot country flags as points on a x, y plane. So I am trying to prompt the user to enter a country name, and after it is plotted, i want the user to be able to enter another country name and for it to be plotted too, without losing the first point of course.

so basically I want the plot to keep updating whenever a user inputs a country. Here's the part of the code:

while True:

user_input = input('Enter Country: ')
for country, i, j, flag in zip(countries, xs, ys, flags):
            if(user_input == item):
                ax.scatter(i, j)
                ab = AnnotationBbox(getImage(path), (i, j), frameon=False)
                ax.add_artist(ab)
                plt.show()
                plt.pause(0.05)
    print("Try Another Country")

It works fine with the first user input. For example, if I input "italy" Italian flag appears on the graph, but when I input the next country name, nothing changes and output keeps giving "Try Another Country"

Please Help!

2 Answers2

1

In addition to @Pietro example, in your case print("Try Another Country") is going to be displayed len(countries) times as you are not breaking the for loop once you have draw the flag.

From what I understand from your code you should only do print("Try Another Country") in the if and break the for loop after.

As i can not comment the thread with @Pietro,maybe you can try something like this in your notebook

import numpy as np
from IPython import display

X = np.linspace(-5, 5, 100)

while True:
    pp = input("Enter the power (int): ")
    display.clear_output(wait=True)
    if pp == "q":
        break
    Y = X ** int(pp)
    
    plt.plot(X,Y)
    plt.show()
Netim
  • 135
  • 7
0

Without access to the list of countries/flags obviously I cannot do it like you, but this should show a way to do this, using line.set_data(X, Y) and fig.canvas.draw() to update the plot:

import matplotlib.pyplot as plt  # type: ignore
import numpy as np  # type: ignore

X = np.linspace(-5, 5, 100)
Y = X ** 2

fig, ax = plt.subplots(1, 1)
fig.show()

# plot returns an iterable of artists, so we unpack it
(line,) = ax.plot(X, Y)
ax.set_ylim(np.min(Y), np.max(Y))

# draw the first plot
fig.canvas.draw()

while True:
    inp = input("Enter the exponent (int): ")
    if inp == "":
        break

    # get new data
    Y = X ** int(inp)

    # update ylims
    ax.set_ylim(np.min(Y), np.max(Y))

    # update the graph
    line.set_data(X, Y)
    fig.canvas.draw()

This example shows line and plot but it should work similarly for scatter. I admit I have never used AnnotationBbox, but I think that you should be able to just add another artist to the axes.

Cheers!

Pietro
  • 1,090
  • 2
  • 9
  • 15
  • Thanks for answer, truly appreciate it! what I am trying to do, is once user enter country name, i compare input to the country names in my premade list(with a loop), and if its there, i plot it(as a flag) based on its premade x and y coordinates, but my issue is it only works with first user input and then no matter how many times i enter country names, nothing changes, i think it is something to do with plt.show() not updating when more than one iterations are entered – Adryan Zeigler Apr 01 '21 at 15:48
  • If the loop/user input is working, can you try using `fig.show()` in the beginning and `fig.canvas.draw()` to update the plot as I do? Does that change something? Also the formatting of the code in the question is not good so it is hard to debug, so fixing that would help. Also x2, you iterate over `country, i, j, flag`, but then use `item` and `path`, so uploading more code would make the problem clearer. – Pietro Apr 01 '21 at 16:48
  • ohhh sorry i must've forgot to change item to country and path to flag, when i was posting it here to make it more readable, excuse me! as for fig.show() it doesnt seem to work, i am on jupyter notebook and it gives me an error... anyway if you have the time i would gladly send the code – Adryan Zeigler Apr 01 '21 at 17:46
  • Getting the code I uploaded to work was quite tricky and I admit I have no idea how to port it to Jupyter. There is `animation.FuncAnimation` as an option that I know works on notebooks but that requires a fixed frame rate rather than being asynchronous so it would be quite hard to wait for user input. – Pietro Apr 01 '21 at 18:34
  • Further reading using [`set_data`](https://stackoverflow.com/a/34486703/2237151) and [`canvas.draw`](https://linux-blog.anracom.com/2019/12/26/matplotlib-jupyter-and-updating-multiple-interactive-plots/) (so actually it might work), [`display`](https://medium.com/@shahinrostami/jupyter-notebook-and-updating-plots-f1ec4cdc354b) and [`func_animation`](http://louistiao.me/posts/notebooks/embedding-matplotlib-animations-in-jupyter-notebooks/). – Pietro Apr 01 '21 at 18:36