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

[Doc] Add Arrow Vector Example #3236

Merged
merged 10 commits into from
Nov 12, 2023
Merged

Conversation

ChiaLingWeng
Copy link
Contributor

This will close #914
@binste I find triangle mark may be more suitable and put this example under case studies section,
feel free to let me know if there's anything can be improved!
image

Copy link
Contributor

@binste binste left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for adding this example! It's something I would have needed in the past, great to finally know how I can achieve a decent arrow :)

I left some minor comments. Could you also replace all single quotes ' with double quotes " in the code?

tests/examples_arguments_syntax/arrow_vector.py Outdated Show resolved Hide resolved
tests/examples_arguments_syntax/arrow_vector.py Outdated Show resolved Hide resolved
@ChiaLingWeng ChiaLingWeng requested a review from binste October 24, 2023 16:53
@joelostblom
Copy link
Contributor

joelostblom commented Oct 25, 2023

This example is great! What do you think about also including a separate example showing how to use unicode arrows (or maybe one of each type of arrow in the same chart/example, that's probably better)? I find this quite useful for simpler things where the length of the arrow does not need to be configured, for example:

image

inertias = 35, 11, 4, 3, 3, 2, 1, 1, 2
alt.layer(
    alt.Chart(
        pd.DataFrame({
            'wssd': inertias,
            'k': range(1, len(inertias) + 1)
        })
    ).mark_line(point=True).encode(
        x=alt.X("k").title("Number of clusters"),
        y=alt.Y("wssd").title("Total within-cluster sum of squares"),
    ),
    alt.Chart().mark_text(size=22, align='left', baseline='bottom').encode(
        x=alt.datum(3.4),
        y=alt.datum(9.8),
        text=alt.datum('Elbow')
    ),
    alt.Chart().mark_text(size=50, align='left', baseline='bottom', fontWeight=100, angle=25).encode(
        x=alt.datum(2.8),
        y=alt.datum(5),
        text=alt.datum('🠃')
    )
)

@ChiaLingWeng
Copy link
Contributor Author

ChiaLingWeng commented Oct 27, 2023

@joelostblom Using unicode arrow is also great!
I think it's better to combine these two example,
below is my attempt (the code may need some cleanup),
one thing I did not notice before is that since x and y axis may be in different scale (not 1:1),
and the theta angle should be adjust accordingly, in this example, I divide the vector by 9 and 35, but I think this step is a little tricky:

price = [35, 11, 4, 3, 3, 2, 1, 1, 2]
data = pd.DataFrame({
            'month': range(1, len(price) + 1),
            'price': price,
        })
unicode_arrow = alt.layer(
    alt.Chart(data).mark_line(point=True).encode(
        x=alt.X("month").title("Month").scale(domain=[1,9]),
        y=alt.Y("price").title("Price"),
    ),
    alt.Chart().mark_text(size=22, align='left', baseline='bottom').encode(
        x=alt.datum(3.4),
        y=alt.datum(9.8),
        text=alt.datum('Release')
    ),
    alt.Chart().mark_text(size=50, align='left', baseline='bottom', fontWeight=100, angle=25).encode(
        x=alt.datum(2.8),
        y=alt.datum(5),
        text=alt.datum('🠃')
    )
)

df = data.copy()
month_2 = df['month'].to_list()[1:]
price_2 = df['price'].to_list()[1:]
df.drop(df.index[-1], inplace=True)
df['month_2'], df['price_2'] = month_2, price_2 

# calculate the vector
df['month_'] = (df['month_2']-df["month"])/9
df['price_'] = (df['price_2']-df["price"])/35

# dot = (x_,y_) dot (0,1) = y_
df["norm"] = np.sqrt(df['month_']**2+df['price_']**2)
df["theta"] = np.degrees(np.arccos(df['price_']/df["norm"]))

lines = alt.Chart(df).mark_line().encode(
    alt.X("month")
    .title('Month')
    .scale(domain=(1, 9)),
    alt.Y("price")
    .title('Price')
    .scale(domain=(0, 35)),
    alt.X2("month_2"),
    alt.Y2("price_2")
)

wedge = alt.Chart(df).mark_point(shape="triangle", filled=True).encode(
    alt.X("month_2"),
    alt.Y("price_2"),
    alt.Angle("theta")
    .scale(domain=[0, 360]),
    alt.SizeValue(50),
    alt.ColorValue('#000000')
)

arrow_vector = lines + wedge

unicode_arrow | arrow_vector

result:
image

@joelostblom
Copy link
Contributor

That second chart is a cool example! Although I wonder how common it is to create arrows like that. For this gallery example, I think it would be helpful if we show the most common use case of an arrow, which I think is for annotations. So if we could make a wedge arrow that looks similar to the current unicode arrow but points at some different location on the line in the same chart, I think that would be helpful.

For you second example here with the many arrows, maybe it would be useful in a chart like this to show the order the points are connected in even more clearly? We could add a second separate example for that if you think that's a good fit, and maybe include a note about the tricky adjustment of the angles that you mentioned.

@ChiaLingWeng
Copy link
Contributor Author

Hi @joelostblom, yes I think showing different method would be better!
image

@ChiaLingWeng ChiaLingWeng deleted the arrow_vector branch November 8, 2023 02:45
@ChiaLingWeng ChiaLingWeng restored the arrow_vector branch November 9, 2023 00:31
@ChiaLingWeng ChiaLingWeng reopened this Nov 9, 2023
@joelostblom
Copy link
Contributor

Super, thanks for all your work on this @ChiaLingWeng ! I really like the new example and I just simplified the code slightly in my latest commit. Will merge when tests are passing.

@joelostblom joelostblom merged commit 65240de into vega:main Nov 12, 2023
10 checks passed
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

Successfully merging this pull request may close these issues.

Arrows?
3 participants