Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Customised Markersize in plot_di #698

Open
aluthfian opened this issue Aug 17, 2023 · 4 comments
Open

Customised Markersize in plot_di #698

aluthfian opened this issue Aug 17, 2023 · 4 comments

Comments

@aluthfian
Copy link

aluthfian commented Aug 17, 2023

Reference

plot_di function

Issue

Older plot_di does not allow straightforward use of numpy.ndarray to define marker size. If the plotted inclination data contains a mix of negative and positive values, the function would throw out an error message saying that the size of marker size array "is not the same as" the inclination and declination array.

Possible Solution

To add an if block to handle markersize array.

Proposed Code

def plot_di(dec=None, inc=None, di_block=None, color='k', marker='o', markersize=20, legend='no', label='', title=None, edge=None,alpha=1):
    """
    Plot declination, inclination data on an equal area plot.

    Before this function is called a plot needs to be initialized with code that looks
    something like:
    >fignum = 1
    >plt.figure(num=fignum,figsize=(10,10),dpi=160)
    >ipmag.plot_net(fignum)

    Parameters:
        dec : declination being plotted
        inc : inclination being plotted
        di_block: a nested list of [dec,inc,1.0] (di_block can be provided instead of dec, inc in which case it will be used)
        color : the default color is black. Other colors can be chosen (e.g. 'r')
        marker : the default marker is a circle ('o')
        markersize : default size is 20, but you can also put a numpy array to define individual marker sizes
        label : the default label is blank ('')
        legend : the default is no legend ('no'). Putting 'yes' will plot a legend.
        edge : marker edge color - if blank, is color of marker
        alpha : opacity
    """
    X_down = []
    X_up = []
    Y_down = []
    Y_up = []
    color_down = []
    color_up = []

    if di_block is not None:
        di_lists = unpack_di_block(di_block)
        if len(di_lists) == 3:
            dec, inc, intensity = di_lists
        if len(di_lists) == 2:
            dec, inc = di_lists
    try:
        length = len(dec)
        for n in range(len(dec)):
            XY = pmag.dimap(dec[n], inc[n])
            if inc[n] >= 0:
                X_down.append(XY[0])
                Y_down.append(XY[1])
                if type(color) == list:
                    color_down.append(color[n])
                else:
                    color_down.append(color)
            else:
                X_up.append(XY[0])
                Y_up.append(XY[1])
                if type(color) == list:
                    color_up.append(color[n])
                else:
                    color_up.append(color)
    except:
        XY = pmag.dimap(dec, inc)
        if inc >= 0:
            X_down.append(XY[0])
            Y_down.append(XY[1])
            color_down.append(color)
        else:
            X_up.append(XY[0])
            Y_up.append(XY[1])
            color_up.append(color)
            
    """
    NEW STUFF to detect array-shaped markersize
    """
    if isinstance(markersize, np.ndarray):
        marker_up = []
        marker_down = []
        for n in range(len(dec)):
            if inc[n] >= 0:
                marker_down.append(markersize[n])
            else:
                marker_up.append(markersize[n])
    else:
        marker_up = markersize
        marker_down = markersize
    """
    END OF NEW STUFF
    """    
        
    if len(X_up) > 0:
        plt.scatter(X_up, Y_up, facecolors='none', edgecolors=color_up,
                    s=marker_up, marker=marker, label=label,alpha=alpha)

    if len(X_down) > 0:
        plt.scatter(X_down, Y_down, facecolors=color_down, edgecolors=edge,
                    s=marker_down, marker=marker, label=label,alpha=alpha)
    if legend == 'yes':
        plt.legend(loc=2)
    plt.tight_layout()
    if title != None:
        plt.title(title)
@Swanson-Hysell
Copy link
Member

Interesting. Can you describe the envisioned use case here? I am used to thinking about markersize as a single value for all points.

@aluthfian
Copy link
Author

aluthfian commented Aug 17, 2023

I can think of one already published use-case here: To plot the declination and inclination of 3D vector magnetic model voxels scaled by the inverse of the standard deviation of model declination values (Miller et al., 2020).

image

@Swanson-Hysell
Copy link
Member

Thanks for the example. In this case, it seems like each once can be put in with a separate call to the function with distinct parameters.

If we are putting in the functionality for variable symbology, it seems like we would want to to be generalized to be markersize and marker and color? With them all being able to be sent in as lists give that the others would be lists of strings. How does this work in default matplotlib functions (e.g. plt.scatter)?

@aluthfian
Copy link
Author

aluthfian commented Aug 17, 2023

it seems like we would want to be generalized to be markersize and marker and color?

For color, yes, I think it can be generalised as well as an alternative to showing variable markersize, but I do not see the likeliness of this being used in general publications since, in my opinion, more people can recognise shapes better than colour (colourblindness issue 😉).

For marker shape, matplotlib does not allow an array to define them. For each plt.scatter call, we are allowed one shape definition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants